1
2
3{ aix 5.3 doesn't have dladdr -> own implementation (from
4  http://root.cern.ch/drupal/content/aix-and-dladdr }
5
6
7  const
8    L_GETINFO = 2;
9
10  type
11    pld_info = ^ld_info;
12    ld_info = record
13      ldinfo_next: cuint;
14{$ifndef cpu64}
15      ldinfo_flags: cuint;
16{$endif}
17      _file: record
18        case byte of
19          0: (_ldinfo_fd: cint);
20          1: (_ldinfo_fp: pointer);
21          2: (_core_offset: ptrint);
22      end;
23      ldinfo_textorg: pointer;
24      ldinfo_textsize: ptrint;
25      ldinfo_dataorg: pointer;
26      ldinfo_datasize: ptrint;
27      ldinfo_filename: pchar;
28    end;
29
30  function loadquery(__lflags: cint; __buffer: pointer; __length: cuint): longint; cdecl; varargs; external;
31
32
33  function aix53_dladdr(Lib: pointer; info: Pdl_info): Longint; cdecl;
34    var
35      buf: array[0..4095] of byte;
36      pbuf: pbyte;
37      ldi: pld_info;
38      text_begin, text_end: pointer;
39    begin
40      fillchar(info^,sizeof(info^),0);
41      aix53_dladdr:=loadquery(L_GETINFO,@buf,sizeof(buf));
42      if aix53_dladdr=-1 then
43        begin
44          aix53_dladdr:=0;
45          exit;
46        end;
47      pbuf:=@buf[0];
48      ldi:=pld_info(pbuf);
49      // First is main(), skip.
50      while ldi^.ldinfo_next<>0 do
51        begin
52          inc(pbuf,ldi^.ldinfo_next);
53          ldi:=pld_info(pbuf);
54          text_begin:=ldi^.ldinfo_textorg;
55          if text_begin<Lib then
56            begin
57              text_end:=text_begin+ldi^.ldinfo_textsize;
58              if text_end>Lib then
59                begin
60                  info^.dli_fname:=ldi^.ldinfo_filename;
61                  info^.dli_fbase:=ldi^.ldinfo_textorg;
62                  { no info about symbols -> leave nil/0 (valid for regular
63                    dladdr call as well) }
64                  aix53_dladdr:=1;
65                  exit;
66                end;
67           end;
68        end;
69      aix53_dladdr:=0;
70    end;
71
72
73  type
74    tdladdrfunc = function(lib: pointer; info: Pdl_info): longint; cdecl;
75
76  function dladdr(Lib: pointer; info: Pdl_info): Longint; cdecl;
77    const
78      dladdrf: tdladdrfunc = nil;
79    var
80      libdl: pointer;
81    begin
82      { dladdr is only available on AIX 6.0 and later.
83
84        AIX does not support undefined weak external symbols, so we cannot
85        simply define dladdr as weakexternal and be done with it -> look up
86        the address of dladdr using dlsym }
87      if not assigned(dladdrf) then
88        begin
89          libdl:=dlopen('libdl.a',RTLD_LAZY);
90          if assigned(libdl) then
91            dladdrf:=tdladdrfunc(dlsym(libdl,'dladdr'));
92          if not assigned(dladdrf) then
93            dladdrf:=@aix53_dladdr;
94          { can't be the last reference that causes it to be unloaded, since
95            most functions from this unit come from it }
96          if assigned(libdl) then
97            dlclose(libdl);
98        end;
99      dladdr:=dladdrf(Lib,info);
100    end;
101
102