TEMP-0000000-B67840.3.c8451af.patch 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. Subject: Split netbsd and freebsd version printing into separate functions (...)
  2. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  3. Date: Tue Nov 5 15:44:01 2013 +0000
  4. Origin: FILE5_15-9-gc8451af
  5. Last-Update: 2015-01-05
  6. - split netbsd and freebsd version printing into separate functions
  7. - don't let the NetBSD pax note end the search for notes
  8. - add 2 more NetBSD notes
  9. (prequisite for TEMP-0000000-B67840)
  10. diff --git a/src/readelf.c b/src/readelf.c
  11. index 87c19a3..18dacdd 100644
  12. --- a/src/readelf.c
  13. +++ b/src/readelf.c
  14. @@ -352,6 +352,126 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
  15. }
  16. #endif
  17. +static void
  18. +do_note_netbsd_version(struct magic_set *ms, int swap, void *v)
  19. +{
  20. + uint32_t desc;
  21. + (void)memcpy(&desc, v, sizeof(desc));
  22. + desc = elf_getu32(swap, desc);
  23. +
  24. + if (file_printf(ms, ", for NetBSD") == -1)
  25. + return;
  26. + /*
  27. + * The version number used to be stuck as 199905, and was thus
  28. + * basically content-free. Newer versions of NetBSD have fixed
  29. + * this and now use the encoding of __NetBSD_Version__:
  30. + *
  31. + * MMmmrrpp00
  32. + *
  33. + * M = major version
  34. + * m = minor version
  35. + * r = release ["",A-Z,Z[A-Z] but numeric]
  36. + * p = patchlevel
  37. + */
  38. + if (desc > 100000000U) {
  39. + uint32_t ver_patch = (desc / 100) % 100;
  40. + uint32_t ver_rel = (desc / 10000) % 100;
  41. + uint32_t ver_min = (desc / 1000000) % 100;
  42. + uint32_t ver_maj = desc / 100000000;
  43. +
  44. + if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
  45. + return;
  46. + if (ver_rel == 0 && ver_patch != 0) {
  47. + if (file_printf(ms, ".%u", ver_patch) == -1)
  48. + return;
  49. + } else if (ver_rel != 0) {
  50. + while (ver_rel > 26) {
  51. + if (file_printf(ms, "Z") == -1)
  52. + return;
  53. + ver_rel -= 26;
  54. + }
  55. + if (file_printf(ms, "%c", 'A' + ver_rel - 1)
  56. + == -1)
  57. + return;
  58. + }
  59. + }
  60. +}
  61. +
  62. +static void
  63. +do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
  64. +{
  65. + uint32_t desc;
  66. +
  67. + (void)memcpy(&desc, v, sizeof(desc));
  68. + desc = elf_getu32(swap, desc);
  69. + if (file_printf(ms, ", for FreeBSD") == -1)
  70. + return;
  71. +
  72. + /*
  73. + * Contents is __FreeBSD_version, whose relation to OS
  74. + * versions is defined by a huge table in the Porter's
  75. + * Handbook. This is the general scheme:
  76. + *
  77. + * Releases:
  78. + * Mmp000 (before 4.10)
  79. + * Mmi0p0 (before 5.0)
  80. + * Mmm0p0
  81. + *
  82. + * Development branches:
  83. + * Mmpxxx (before 4.6)
  84. + * Mmp1xx (before 4.10)
  85. + * Mmi1xx (before 5.0)
  86. + * M000xx (pre-M.0)
  87. + * Mmm1xx
  88. + *
  89. + * M = major version
  90. + * m = minor version
  91. + * i = minor version increment (491000 -> 4.10)
  92. + * p = patchlevel
  93. + * x = revision
  94. + *
  95. + * The first release of FreeBSD to use ELF by default
  96. + * was version 3.0.
  97. + */
  98. + if (desc == 460002) {
  99. + if (file_printf(ms, " 4.6.2") == -1)
  100. + return;
  101. + } else if (desc < 460100) {
  102. + if (file_printf(ms, " %d.%d", desc / 100000,
  103. + desc / 10000 % 10) == -1)
  104. + return;
  105. + if (desc / 1000 % 10 > 0)
  106. + if (file_printf(ms, ".%d", desc / 1000 % 10) == -1)
  107. + return;
  108. + if ((desc % 1000 > 0) || (desc % 100000 == 0))
  109. + if (file_printf(ms, " (%d)", desc) == -1)
  110. + return;
  111. + } else if (desc < 500000) {
  112. + if (file_printf(ms, " %d.%d", desc / 100000,
  113. + desc / 10000 % 10 + desc / 1000 % 10) == -1)
  114. + return;
  115. + if (desc / 100 % 10 > 0) {
  116. + if (file_printf(ms, " (%d)", desc) == -1)
  117. + return;
  118. + } else if (desc / 10 % 10 > 0) {
  119. + if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
  120. + return;
  121. + }
  122. + } else {
  123. + if (file_printf(ms, " %d.%d", desc / 100000,
  124. + desc / 1000 % 100) == -1)
  125. + return;
  126. + if ((desc / 100 % 10 > 0) ||
  127. + (desc % 100000 / 100 == 0)) {
  128. + if (file_printf(ms, " (%d)", desc) == -1)
  129. + return;
  130. + } else if (desc / 10 % 10 > 0) {
  131. + if (file_printf(ms, ".%d", desc / 10 % 10) == -1)
  132. + return;
  133. + }
  134. + }
  135. +}
  136. +
  137. private size_t
  138. donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  139. int clazz, int swap, size_t align, int *flags)
  140. @@ -498,131 +618,41 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  141. pax[i]) == -1)
  142. return size;
  143. }
  144. - *flags |= FLAGS_DID_BUILD_ID;
  145. }
  146. - if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
  147. - xnh_type == NT_NETBSD_VERSION && descsz == 4) {
  148. - uint32_t desc;
  149. - (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
  150. - desc = elf_getu32(swap, desc);
  151. -
  152. - if (file_printf(ms, ", for NetBSD") == -1)
  153. - return size;
  154. - /*
  155. - * The version number used to be stuck as 199905, and was thus
  156. - * basically content-free. Newer versions of NetBSD have fixed
  157. - * this and now use the encoding of __NetBSD_Version__:
  158. - *
  159. - * MMmmrrpp00
  160. - *
  161. - * M = major version
  162. - * m = minor version
  163. - * r = release ["",A-Z,Z[A-Z] but numeric]
  164. - * p = patchlevel
  165. - */
  166. - if (desc > 100000000U) {
  167. - uint32_t ver_patch = (desc / 100) % 100;
  168. - uint32_t ver_rel = (desc / 10000) % 100;
  169. - uint32_t ver_min = (desc / 1000000) % 100;
  170. - uint32_t ver_maj = desc / 100000000;
  171. -
  172. - if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
  173. + if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
  174. + switch (xnh_type) {
  175. + case NT_NETBSD_VERSION:
  176. + if (descsz == 4) {
  177. + do_note_netbsd_version(ms, swap, &nbuf[doff]);
  178. + *flags |= FLAGS_DID_NOTE;
  179. return size;
  180. - if (ver_rel == 0 && ver_patch != 0) {
  181. - if (file_printf(ms, ".%u", ver_patch) == -1)
  182. - return size;
  183. - } else if (ver_rel != 0) {
  184. - while (ver_rel > 26) {
  185. - if (file_printf(ms, "Z") == -1)
  186. - return size;
  187. - ver_rel -= 26;
  188. - }
  189. - if (file_printf(ms, "%c", 'A' + ver_rel - 1)
  190. - == -1)
  191. - return size;
  192. }
  193. + break;
  194. + case NT_NETBSD_MARCH:
  195. + if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
  196. + (const char *)&nbuf[doff]) == -1)
  197. + return size;
  198. + break;
  199. + case NT_NETBSD_CMODEL:
  200. + if (file_printf(ms, ", compiler model: %.*s",
  201. + (int)descsz, (const char *)&nbuf[doff]) == -1)
  202. + return size;
  203. + break;
  204. + default:
  205. + if (file_printf(ms, ", note=%u", xnh_type) == -1)
  206. + return size;
  207. + break;
  208. }
  209. - *flags |= FLAGS_DID_NOTE;
  210. return size;
  211. }
  212. - if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
  213. - xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
  214. - uint32_t desc;
  215. - (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
  216. - desc = elf_getu32(swap, desc);
  217. - if (file_printf(ms, ", for FreeBSD") == -1)
  218. + if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
  219. + if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
  220. + do_note_freebsd_version(ms, swap, &nbuf[doff]);
  221. + *flags |= FLAGS_DID_NOTE;
  222. return size;
  223. -
  224. - /*
  225. - * Contents is __FreeBSD_version, whose relation to OS
  226. - * versions is defined by a huge table in the Porter's
  227. - * Handbook. This is the general scheme:
  228. - *
  229. - * Releases:
  230. - * Mmp000 (before 4.10)
  231. - * Mmi0p0 (before 5.0)
  232. - * Mmm0p0
  233. - *
  234. - * Development branches:
  235. - * Mmpxxx (before 4.6)
  236. - * Mmp1xx (before 4.10)
  237. - * Mmi1xx (before 5.0)
  238. - * M000xx (pre-M.0)
  239. - * Mmm1xx
  240. - *
  241. - * M = major version
  242. - * m = minor version
  243. - * i = minor version increment (491000 -> 4.10)
  244. - * p = patchlevel
  245. - * x = revision
  246. - *
  247. - * The first release of FreeBSD to use ELF by default
  248. - * was version 3.0.
  249. - */
  250. - if (desc == 460002) {
  251. - if (file_printf(ms, " 4.6.2") == -1)
  252. - return size;
  253. - } else if (desc < 460100) {
  254. - if (file_printf(ms, " %d.%d", desc / 100000,
  255. - desc / 10000 % 10) == -1)
  256. - return size;
  257. - if (desc / 1000 % 10 > 0)
  258. - if (file_printf(ms, ".%d", desc / 1000 % 10)
  259. - == -1)
  260. - return size;
  261. - if ((desc % 1000 > 0) || (desc % 100000 == 0))
  262. - if (file_printf(ms, " (%d)", desc) == -1)
  263. - return size;
  264. - } else if (desc < 500000) {
  265. - if (file_printf(ms, " %d.%d", desc / 100000,
  266. - desc / 10000 % 10 + desc / 1000 % 10) == -1)
  267. - return size;
  268. - if (desc / 100 % 10 > 0) {
  269. - if (file_printf(ms, " (%d)", desc) == -1)
  270. - return size;
  271. - } else if (desc / 10 % 10 > 0) {
  272. - if (file_printf(ms, ".%d", desc / 10 % 10)
  273. - == -1)
  274. - return size;
  275. - }
  276. - } else {
  277. - if (file_printf(ms, " %d.%d", desc / 100000,
  278. - desc / 1000 % 100) == -1)
  279. - return size;
  280. - if ((desc / 100 % 10 > 0) ||
  281. - (desc % 100000 / 100 == 0)) {
  282. - if (file_printf(ms, " (%d)", desc) == -1)
  283. - return size;
  284. - } else if (desc / 10 % 10 > 0) {
  285. - if (file_printf(ms, ".%d", desc / 10 % 10)
  286. - == -1)
  287. - return size;
  288. - }
  289. }
  290. - *flags |= FLAGS_DID_NOTE;
  291. - return size;
  292. }
  293. if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
  294. diff --git a/src/readelf.h b/src/readelf.h
  295. index df6955c..9ada14d 100644
  296. --- a/src/readelf.h
  297. +++ b/src/readelf.h
  298. @@ -280,6 +280,29 @@ typedef struct {
  299. #define NT_NETBSD_PAX_ASLR 0x10 /* Force enable ASLR */
  300. #define NT_NETBSD_PAX_NOASLR 0x20 /* Force disable ASLR */
  301. +/*
  302. + * NetBSD-specific note type: MACHINE_ARCH.
  303. + * There should be 1 NOTE per executable.
  304. + * name: NetBSD\0
  305. + * namesz: 7
  306. + * desc: string
  307. + * descsz: variable
  308. + */
  309. +#define NT_NETBSD_MARCH 5
  310. +
  311. +/*
  312. + * NetBSD-specific note type: COMPILER MODEL.
  313. + * There should be 1 NOTE per executable.
  314. + * name: NetBSD\0
  315. + * namesz: 7
  316. + * desc: string
  317. + * descsz: variable
  318. + */
  319. +#define NT_NETBSD_CMODEL 6
  320. +
  321. +#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
  322. +#define ELFSIZE ARCH_ELFSIZE
  323. +#endif
  324. /* SunOS 5.x hardware/software capabilities */
  325. typedef struct {
  326. Elf32_Word c_tag;