dlaix.inc 2.8 KB

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