abilist.awk 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # This awk script processes the output of objdump --dynamic-syms
  2. # into a simple format that should not change when the ABI is not changing.
  3. BEGIN {
  4. if (combine_fullname)
  5. combine = 1;
  6. if (combine)
  7. parse_names = 1;
  8. }
  9. # Per-file header.
  10. /[^ :]+\.so\.[0-9.]+:[ ]+.file format .*$/ {
  11. emit(0);
  12. seen_opd = 0;
  13. sofullname = $1;
  14. sub(/:$/, "", sofullname);
  15. soname = sofullname;
  16. sub(/^.*\//, "", soname);
  17. sub(/\.so\.[0-9.]+$/, "", soname);
  18. suppress = ((filename_regexp != "" && sofullname !~ filename_regexp) \
  19. || (libname_regexp != "" && soname !~ libname_regexp));
  20. next
  21. }
  22. suppress { next }
  23. # Normalize columns.
  24. /^[0-9a-fA-F]+ / { sub(/ /, " - ") }
  25. # Skip undefineds.
  26. $4 == "*UND*" { next }
  27. # Skip locals.
  28. $2 == "l" { next }
  29. # If the target uses ST_OTHER, it will be output before the symbol name.
  30. $2 == "g" || $2 == "w" && (NF == 7 || NF == 8) {
  31. type = $3;
  32. size = $5;
  33. sub(/^0*/, "", size);
  34. if (size == "") {
  35. size = " 0x0";
  36. } else {
  37. size = " 0x" size;
  38. }
  39. version = $6;
  40. symbol = $NF;
  41. gsub(/[()]/, "", version);
  42. # binutils versions up through at least 2.23 have some bugs that
  43. # caused STV_HIDDEN symbols to appear in .dynsym, though that is useless.
  44. if (NF > 7 && $7 == ".hidden") next;
  45. if (version == "GLIBC_PRIVATE") next;
  46. desc = "";
  47. if (type == "D" && ($4 == ".tbss" || $4 == ".tdata")) {
  48. type = "T";
  49. }
  50. else if (type == "D" && $4 == ".opd") {
  51. type = "F";
  52. size = "";
  53. if (seen_opd < 0)
  54. type = "O";
  55. seen_opd = 1;
  56. }
  57. else if (type == "D" && NF == 8 && $7 == "0x80") {
  58. # Alpha functions avoiding plt entry in users
  59. type = "F";
  60. size = "";
  61. seen_opd = -1;
  62. }
  63. else if ($4 == "*ABS*") {
  64. next;
  65. }
  66. else if (type == "D") {
  67. # Accept unchanged.
  68. }
  69. else if (type == "DO") {
  70. type = "D";
  71. }
  72. else if (type == "DF") {
  73. if (symbol ~ /^\./ && seen_opd >= 0)
  74. next;
  75. seen_opd = -1;
  76. type = "F";
  77. size = "";
  78. }
  79. else if (type == "iD" && ($4 == ".text" || $4 == ".opd")) {
  80. # Indirect functions.
  81. type = "F";
  82. size = "";
  83. }
  84. else {
  85. print "ERROR: Unable to handle this type of symbol:", $0
  86. exit 1
  87. }
  88. if (desc == "")
  89. desc = symbol " " type size;
  90. if (combine)
  91. version = soname " " version (combine_fullname ? " " sofullname : "");
  92. # Append to the string which collects the results.
  93. descs = descs version " " desc "\n";
  94. next;
  95. }
  96. # Header crapola.
  97. NF == 0 || /DYNAMIC SYMBOL TABLE/ || /file format/ { next }
  98. {
  99. print "ERROR: Unable to interpret this line:", $0
  100. exit 1
  101. }
  102. function emit(end) {
  103. if (!end && (combine || ! parse_names || soname == ""))
  104. return;
  105. tofile = parse_names && !combine;
  106. if (tofile) {
  107. out = prefix soname ".symlist";
  108. if (soname in outfiles)
  109. out = out "." ++outfiles[soname];
  110. else
  111. outfiles[soname] = 1;
  112. outpipe = "LC_ALL=C sort -u > " out;
  113. } else {
  114. outpipe = "LC_ALL=C sort -u";
  115. }
  116. printf "%s", descs | outpipe;
  117. descs = "";
  118. if (tofile)
  119. print "wrote", out, "for", sofullname;
  120. }
  121. END {
  122. emit(1);
  123. }