outelf.c 113 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2017 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. /*
  34. * Common code for outelf32 and outelf64
  35. */
  36. #include "compiler.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include "nasm.h"
  40. #include "nasmlib.h"
  41. #include "error.h"
  42. #include "saa.h"
  43. #include "raa.h"
  44. #include "stdscan.h"
  45. #include "eval.h"
  46. #include "outform.h"
  47. #include "outlib.h"
  48. #include "rbtree.h"
  49. #include "ver.h"
  50. #include "dwarf.h"
  51. #include "stabs.h"
  52. #include "outelf.h"
  53. #include "elf.h"
  54. #if defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32)
  55. #define SECT_DELTA 32
  56. static struct elf_section **sects;
  57. static int nsects, sectlen;
  58. #define SHSTR_DELTA 256
  59. static char *shstrtab;
  60. static int shstrtablen, shstrtabsize;
  61. static struct SAA *syms;
  62. static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */
  63. static int32_t def_seg;
  64. static struct RAA *bsym;
  65. static struct SAA *strs;
  66. static uint32_t strslen;
  67. static struct elf_symbol *fwds;
  68. static char elf_module[FILENAME_MAX];
  69. extern const struct ofmt of_elf32;
  70. extern const struct ofmt of_elf64;
  71. extern const struct ofmt of_elfx32;
  72. static struct ELF_SECTDATA {
  73. void *data;
  74. int64_t len;
  75. bool is_saa;
  76. } *elf_sects;
  77. static int elf_nsect, nsections;
  78. static int64_t elf_foffs;
  79. static void elf_write(void);
  80. static void elf_sect_write(struct elf_section *, const void *, size_t);
  81. static void elf_sect_writeaddr(struct elf_section *, int64_t, size_t);
  82. static void elf_section_header(int, int, uint64_t, void *, bool, uint64_t, int, int,
  83. int, int);
  84. static void elf_write_sections(void);
  85. static struct SAA *elf_build_symtab(int32_t *, int32_t *);
  86. static struct SAA *elf_build_reltab(uint64_t *, struct elf_reloc *);
  87. static void add_sectname(const char *, const char *);
  88. struct erel {
  89. int offset;
  90. int info;
  91. };
  92. struct symlininfo {
  93. int offset;
  94. int section; /* index into sects[] */
  95. int segto; /* internal section number */
  96. char *name; /* shallow-copied pointer of section name */
  97. };
  98. struct linelist {
  99. struct linelist *next;
  100. struct linelist *last;
  101. struct symlininfo info;
  102. char *filename;
  103. int line;
  104. };
  105. struct sectlist {
  106. struct SAA *psaa;
  107. int section;
  108. int line;
  109. int offset;
  110. int file;
  111. struct sectlist *next;
  112. struct sectlist *last;
  113. };
  114. /* common debug variables */
  115. static int currentline = 1;
  116. static int debug_immcall = 0;
  117. /* stabs debug variables */
  118. static struct linelist *stabslines = 0;
  119. static int numlinestabs = 0;
  120. static char *stabs_filename = 0;
  121. static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
  122. static int stablen, stabstrlen, stabrellen;
  123. /* dwarf debug variables */
  124. static struct linelist *dwarf_flist = 0, *dwarf_clist = 0, *dwarf_elist = 0;
  125. static struct sectlist *dwarf_fsect = 0, *dwarf_csect = 0, *dwarf_esect = 0;
  126. static int dwarf_numfiles = 0, dwarf_nsections;
  127. static uint8_t *arangesbuf = 0, *arangesrelbuf = 0, *pubnamesbuf = 0, *infobuf = 0, *inforelbuf = 0,
  128. *abbrevbuf = 0, *linebuf = 0, *linerelbuf = 0, *framebuf = 0, *locbuf = 0;
  129. static int8_t line_base = -5, line_range = 14, opcode_base = 13;
  130. static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
  131. abbrevlen, linelen, linerellen, framelen, loclen;
  132. static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
  133. static struct elf_symbol *lastsym;
  134. /* common debugging routines */
  135. static void debug_typevalue(int32_t);
  136. /* stabs debugging routines */
  137. static void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
  138. static void stabs_output(int, void *);
  139. static void stabs_generate(void);
  140. static void stabs_cleanup(void);
  141. /* dwarf debugging routines */
  142. static void dwarf_init(void);
  143. static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
  144. static void dwarf_output(int, void *);
  145. static void dwarf_generate(void);
  146. static void dwarf_cleanup(void);
  147. static void dwarf_findfile(const char *);
  148. static void dwarf_findsect(const int);
  149. static bool is_elf64(void);
  150. static bool is_elf32(void);
  151. static bool is_elfx32(void);
  152. static bool dfmt_is_stabs(void);
  153. static bool dfmt_is_dwarf(void);
  154. /*
  155. * Special NASM section numbers which are used to define ELF special
  156. * symbols.
  157. */
  158. static int32_t elf_gotpc_sect, elf_gotoff_sect;
  159. static int32_t elf_got_sect, elf_plt_sect;
  160. static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
  161. uint8_t elf_osabi = 0; /* Default OSABI = 0 (System V or Linux) */
  162. uint8_t elf_abiver = 0; /* Current ABI version */
  163. const struct elf_known_section elf_known_sections[] = {
  164. { ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16 },
  165. { ".rodata", SHT_PROGBITS, SHF_ALLOC, 4 },
  166. { ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4 },
  167. { ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
  168. { ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
  169. { ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
  170. { ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
  171. { ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
  172. { ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
  173. { ".comment", SHT_PROGBITS, 0, 1 },
  174. { NULL, SHT_PROGBITS, SHF_ALLOC, 1 } /* default */
  175. };
  176. /* parse section attributes */
  177. static void elf_section_attrib(char *name, char *attr, int pass,
  178. uint32_t *flags_and, uint32_t *flags_or,
  179. uint64_t *align, int *type)
  180. {
  181. char *opt, *val, *next;
  182. opt = nasm_skip_spaces(attr);
  183. if (!opt || !*opt)
  184. return;
  185. while ((opt = nasm_opt_val(opt, &val, &next))) {
  186. if (!nasm_stricmp(opt, "align")) {
  187. if (!val) {
  188. nasm_error(ERR_NONFATAL,
  189. "section align without value specified");
  190. } else {
  191. *align = atoi(val);
  192. if (*align == 0) {
  193. *align = SHA_ANY;
  194. } else if (!is_power2(*align)) {
  195. nasm_error(ERR_NONFATAL,
  196. "section alignment %"PRId64" is not a power of two",
  197. *align);
  198. *align = SHA_ANY;
  199. }
  200. }
  201. } else if (!nasm_stricmp(opt, "alloc")) {
  202. *flags_and |= SHF_ALLOC;
  203. *flags_or |= SHF_ALLOC;
  204. } else if (!nasm_stricmp(opt, "noalloc")) {
  205. *flags_and |= SHF_ALLOC;
  206. *flags_or &= ~SHF_ALLOC;
  207. } else if (!nasm_stricmp(opt, "exec")) {
  208. *flags_and |= SHF_EXECINSTR;
  209. *flags_or |= SHF_EXECINSTR;
  210. } else if (!nasm_stricmp(opt, "noexec")) {
  211. *flags_and |= SHF_EXECINSTR;
  212. *flags_or &= ~SHF_EXECINSTR;
  213. } else if (!nasm_stricmp(opt, "write")) {
  214. *flags_and |= SHF_WRITE;
  215. *flags_or |= SHF_WRITE;
  216. } else if (!nasm_stricmp(opt, "tls")) {
  217. *flags_and |= SHF_TLS;
  218. *flags_or |= SHF_TLS;
  219. } else if (!nasm_stricmp(opt, "nowrite")) {
  220. *flags_and |= SHF_WRITE;
  221. *flags_or &= ~SHF_WRITE;
  222. } else if (!nasm_stricmp(opt, "progbits")) {
  223. *type = SHT_PROGBITS;
  224. } else if (!nasm_stricmp(opt, "nobits")) {
  225. *type = SHT_NOBITS;
  226. } else if (pass == 1) {
  227. nasm_error(ERR_WARNING,
  228. "Unknown section attribute '%s' ignored on"
  229. " declaration of section `%s'", opt, name);
  230. }
  231. opt = next;
  232. }
  233. }
  234. static enum directive_result
  235. elf_directive(enum directive directive, char *value, int pass)
  236. {
  237. int64_t n;
  238. bool err;
  239. char *p;
  240. switch (directive) {
  241. case D_OSABI:
  242. if (pass == 2)
  243. return DIRR_OK; /* ignore in pass 2 */
  244. n = readnum(value, &err);
  245. if (err) {
  246. nasm_error(ERR_NONFATAL, "`osabi' directive requires a parameter");
  247. return DIRR_ERROR;
  248. }
  249. if (n < 0 || n > 255) {
  250. nasm_error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
  251. return DIRR_ERROR;
  252. }
  253. elf_osabi = n;
  254. elf_abiver = 0;
  255. p = strchr(value,',');
  256. if (!p)
  257. return DIRR_OK;
  258. n = readnum(p + 1, &err);
  259. if (err || n < 0 || n > 255) {
  260. nasm_error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
  261. return DIRR_ERROR;
  262. }
  263. elf_abiver = n;
  264. return DIRR_OK;
  265. default:
  266. return DIRR_UNKNOWN;
  267. }
  268. }
  269. static void elf_init(void)
  270. {
  271. strlcpy(elf_module, inname, sizeof(elf_module));
  272. sects = NULL;
  273. nsects = sectlen = 0;
  274. syms = saa_init((int32_t)sizeof(struct elf_symbol));
  275. nlocals = nglobs = ndebugs = 0;
  276. bsym = raa_init();
  277. strs = saa_init(1L);
  278. saa_wbytes(strs, "\0", 1L);
  279. saa_wbytes(strs, elf_module, strlen(elf_module)+1);
  280. strslen = 2 + strlen(elf_module);
  281. shstrtab = NULL;
  282. shstrtablen = shstrtabsize = 0;;
  283. add_sectname("", "");
  284. fwds = NULL;
  285. /*
  286. * FIXME: tlsie is Elf32 only and
  287. * gottpoff is Elfx32|64 only.
  288. */
  289. elf_gotpc_sect = seg_alloc();
  290. backend_label("..gotpc", elf_gotpc_sect + 1, 0L);
  291. elf_gotoff_sect = seg_alloc();
  292. backend_label("..gotoff", elf_gotoff_sect + 1, 0L);
  293. elf_got_sect = seg_alloc();
  294. backend_label("..got", elf_got_sect + 1, 0L);
  295. elf_plt_sect = seg_alloc();
  296. backend_label("..plt", elf_plt_sect + 1, 0L);
  297. elf_sym_sect = seg_alloc();
  298. backend_label("..sym", elf_sym_sect + 1, 0L);
  299. elf_gottpoff_sect = seg_alloc();
  300. backend_label("..gottpoff", elf_gottpoff_sect + 1, 0L);
  301. elf_tlsie_sect = seg_alloc();
  302. backend_label("..tlsie", elf_tlsie_sect + 1, 0L);
  303. def_seg = seg_alloc();
  304. }
  305. static void elf_cleanup(void)
  306. {
  307. struct elf_reloc *r;
  308. int i;
  309. elf_write();
  310. for (i = 0; i < nsects; i++) {
  311. if (sects[i]->type != SHT_NOBITS)
  312. saa_free(sects[i]->data);
  313. if (sects[i]->head)
  314. saa_free(sects[i]->rel);
  315. while (sects[i]->head) {
  316. r = sects[i]->head;
  317. sects[i]->head = sects[i]->head->next;
  318. nasm_free(r);
  319. }
  320. }
  321. nasm_free(sects);
  322. saa_free(syms);
  323. raa_free(bsym);
  324. saa_free(strs);
  325. dfmt->cleanup();
  326. }
  327. /* add entry to the elf .shstrtab section */
  328. static void add_sectname(const char *firsthalf, const char *secondhalf)
  329. {
  330. int len = strlen(firsthalf) + strlen(secondhalf);
  331. while (shstrtablen + len + 1 > shstrtabsize)
  332. shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
  333. strcpy(shstrtab + shstrtablen, firsthalf);
  334. strcat(shstrtab + shstrtablen, secondhalf);
  335. shstrtablen += len + 1;
  336. }
  337. static int elf_make_section(char *name, int type, int flags, int align)
  338. {
  339. struct elf_section *s;
  340. s = nasm_zalloc(sizeof(*s));
  341. if (type != SHT_NOBITS)
  342. s->data = saa_init(1L);
  343. s->tail = &s->head;
  344. if (!strcmp(name, ".text"))
  345. s->index = def_seg;
  346. else
  347. s->index = seg_alloc();
  348. add_sectname("", name);
  349. s->name = nasm_strdup(name);
  350. s->type = type;
  351. s->flags = flags;
  352. s->align = align;
  353. if (nsects >= sectlen)
  354. sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
  355. sects[nsects++] = s;
  356. return nsects - 1;
  357. }
  358. static int32_t elf_section_names(char *name, int pass, int *bits)
  359. {
  360. char *p;
  361. uint32_t flags, flags_and, flags_or;
  362. uint64_t align;
  363. int type, i;
  364. if (!name) {
  365. *bits = ofmt->maxbits;
  366. return def_seg;
  367. }
  368. p = nasm_skip_word(name);
  369. if (*p)
  370. *p++ = '\0';
  371. flags_and = flags_or = type = align = 0;
  372. elf_section_attrib(name, p, pass, &flags_and,
  373. &flags_or, &align, &type);
  374. if (!strcmp(name, ".shstrtab") ||
  375. !strcmp(name, ".symtab") ||
  376. !strcmp(name, ".strtab")) {
  377. nasm_error(ERR_NONFATAL, "attempt to redefine reserved section"
  378. "name `%s'", name);
  379. return NO_SEG;
  380. }
  381. for (i = 0; i < nsects; i++)
  382. if (!strcmp(name, sects[i]->name))
  383. break;
  384. if (i == nsects) {
  385. const struct elf_known_section *ks = elf_known_sections;
  386. while (ks->name) {
  387. if (!strcmp(name, ks->name))
  388. break;
  389. ks++;
  390. }
  391. type = type ? type : ks->type;
  392. align = align ? align : ks->align;
  393. flags = (ks->flags & ~flags_and) | flags_or;
  394. i = elf_make_section(name, type, flags, align);
  395. } else if (pass == 1) {
  396. if ((type && sects[i]->type != type)
  397. || (align && sects[i]->align != align)
  398. || (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
  399. nasm_error(ERR_WARNING, "incompatible section attributes ignored on"
  400. " redeclaration of section `%s'", name);
  401. }
  402. return sects[i]->index;
  403. }
  404. static void elf_deflabel(char *name, int32_t segment, int64_t offset,
  405. int is_global, char *special)
  406. {
  407. int pos = strslen;
  408. struct elf_symbol *sym;
  409. bool special_used = false;
  410. #if defined(DEBUG) && DEBUG>2
  411. nasm_error(ERR_DEBUG,
  412. " elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
  413. name, segment, offset, is_global, special);
  414. #endif
  415. if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
  416. /*
  417. * This is a NASM special symbol. We never allow it into
  418. * the ELF symbol table, even if it's a valid one. If it
  419. * _isn't_ a valid one, we should barf immediately.
  420. *
  421. * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
  422. */
  423. if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
  424. strcmp(name, "..got") && strcmp(name, "..plt") &&
  425. strcmp(name, "..sym") && strcmp(name, "..gottpoff") &&
  426. strcmp(name, "..tlsie"))
  427. nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
  428. return;
  429. }
  430. if (is_global == 3) {
  431. struct elf_symbol **s;
  432. /*
  433. * Fix up a forward-reference symbol size from the first
  434. * pass.
  435. */
  436. for (s = &fwds; *s; s = &(*s)->nextfwd)
  437. if (!strcmp((*s)->name, name)) {
  438. struct tokenval tokval;
  439. expr *e;
  440. char *p = nasm_skip_spaces(nasm_skip_word(special));
  441. stdscan_reset();
  442. stdscan_set(p);
  443. tokval.t_type = TOKEN_INVALID;
  444. e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
  445. if (e) {
  446. if (!is_simple(e))
  447. nasm_error(ERR_NONFATAL, "cannot use relocatable"
  448. " expression as symbol size");
  449. else
  450. (*s)->size = reloc_value(e);
  451. }
  452. /*
  453. * Remove it from the list of unresolved sizes.
  454. */
  455. nasm_free((*s)->name);
  456. *s = (*s)->nextfwd;
  457. return;
  458. }
  459. return; /* it wasn't an important one */
  460. }
  461. saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
  462. strslen += 1 + strlen(name);
  463. lastsym = sym = saa_wstruct(syms);
  464. memset(&sym->symv, 0, sizeof(struct rbtree));
  465. sym->strpos = pos;
  466. sym->type = is_global ? SYM_GLOBAL : SYM_LOCAL;
  467. sym->other = STV_DEFAULT;
  468. sym->size = 0;
  469. if (segment == NO_SEG)
  470. sym->section = SHN_ABS;
  471. else {
  472. int i;
  473. sym->section = SHN_UNDEF;
  474. if (segment == def_seg) {
  475. /* we have to be sure at least text section is there */
  476. int tempint;
  477. if (segment != elf_section_names(".text", 2, &tempint))
  478. nasm_panic(0, "strange segment conditions in ELF driver");
  479. }
  480. for (i = 0; i < nsects; i++) {
  481. if (segment == sects[i]->index) {
  482. sym->section = i + 1;
  483. break;
  484. }
  485. }
  486. }
  487. if (is_global == 2) {
  488. sym->size = offset;
  489. sym->symv.key = 0;
  490. sym->section = SHN_COMMON;
  491. /*
  492. * We have a common variable. Check the special text to see
  493. * if it's a valid number and power of two; if so, store it
  494. * as the alignment for the common variable.
  495. */
  496. if (special) {
  497. bool err;
  498. sym->symv.key = readnum(special, &err);
  499. if (err)
  500. nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
  501. " valid number", special);
  502. else if ((sym->symv.key | (sym->symv.key - 1)) != 2 * sym->symv.key - 1)
  503. nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
  504. " power of two", special);
  505. }
  506. special_used = true;
  507. } else
  508. sym->symv.key = (sym->section == SHN_UNDEF ? 0 : offset);
  509. if (sym->type == SYM_GLOBAL) {
  510. /*
  511. * If sym->section == SHN_ABS, then the first line of the
  512. * else section would cause a core dump, because its a reference
  513. * beyond the end of the section array.
  514. * This behaviour is exhibited by this code:
  515. * GLOBAL crash_nasm
  516. * crash_nasm equ 0
  517. * To avoid such a crash, such requests are silently discarded.
  518. * This may not be the best solution.
  519. */
  520. if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
  521. bsym = raa_write(bsym, segment, nglobs);
  522. } else if (sym->section != SHN_ABS) {
  523. /*
  524. * This is a global symbol; so we must add it to the rbtree
  525. * of global symbols in its section.
  526. *
  527. * In addition, we check the special text for symbol
  528. * type and size information.
  529. */
  530. sects[sym->section-1]->gsyms =
  531. rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
  532. if (special) {
  533. int n = strcspn(special, " \t");
  534. if (!nasm_strnicmp(special, "function", n))
  535. sym->type |= STT_FUNC;
  536. else if (!nasm_strnicmp(special, "data", n) ||
  537. !nasm_strnicmp(special, "object", n))
  538. sym->type |= STT_OBJECT;
  539. else if (!nasm_strnicmp(special, "notype", n))
  540. sym->type |= STT_NOTYPE;
  541. else
  542. nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
  543. n, special);
  544. special += n;
  545. special = nasm_skip_spaces(special);
  546. if (*special) {
  547. n = strcspn(special, " \t");
  548. if (!nasm_strnicmp(special, "default", n))
  549. sym->other = STV_DEFAULT;
  550. else if (!nasm_strnicmp(special, "internal", n))
  551. sym->other = STV_INTERNAL;
  552. else if (!nasm_strnicmp(special, "hidden", n))
  553. sym->other = STV_HIDDEN;
  554. else if (!nasm_strnicmp(special, "protected", n))
  555. sym->other = STV_PROTECTED;
  556. else
  557. n = 0;
  558. special += n;
  559. }
  560. if (*special) {
  561. struct tokenval tokval;
  562. expr *e;
  563. int fwd = 0;
  564. char *saveme = stdscan_get();
  565. while (special[n] && nasm_isspace(special[n]))
  566. n++;
  567. /*
  568. * We have a size expression; attempt to
  569. * evaluate it.
  570. */
  571. stdscan_reset();
  572. stdscan_set(special + n);
  573. tokval.t_type = TOKEN_INVALID;
  574. e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
  575. if (fwd) {
  576. sym->nextfwd = fwds;
  577. fwds = sym;
  578. sym->name = nasm_strdup(name);
  579. } else if (e) {
  580. if (!is_simple(e))
  581. nasm_error(ERR_NONFATAL, "cannot use relocatable"
  582. " expression as symbol size");
  583. else
  584. sym->size = reloc_value(e);
  585. }
  586. stdscan_set(saveme);
  587. }
  588. special_used = true;
  589. }
  590. /*
  591. * If TLS segment, mark symbol accordingly.
  592. */
  593. if (sects[sym->section - 1]->flags & SHF_TLS) {
  594. sym->type &= 0xf0;
  595. sym->type |= STT_TLS;
  596. }
  597. }
  598. sym->globnum = nglobs;
  599. nglobs++;
  600. } else
  601. nlocals++;
  602. if (special && !special_used)
  603. nasm_error(ERR_NONFATAL, "no special symbol features supported here");
  604. }
  605. static void elf_add_reloc(struct elf_section *sect, int32_t segment,
  606. int64_t offset, int type)
  607. {
  608. struct elf_reloc *r;
  609. r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
  610. sect->tail = &r->next;
  611. r->address = sect->len;
  612. r->offset = offset;
  613. if (segment != NO_SEG) {
  614. int i;
  615. for (i = 0; i < nsects; i++)
  616. if (segment == sects[i]->index)
  617. r->symbol = i + 2;
  618. if (!r->symbol)
  619. r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
  620. }
  621. r->type = type;
  622. sect->nrelocs++;
  623. }
  624. /*
  625. * This routine deals with ..got and ..sym relocations: the more
  626. * complicated kinds. In shared-library writing, some relocations
  627. * with respect to global symbols must refer to the precise symbol
  628. * rather than referring to an offset from the base of the section
  629. * _containing_ the symbol. Such relocations call to this routine,
  630. * which searches the symbol list for the symbol in question.
  631. *
  632. * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
  633. * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
  634. * The boolean argument `exact' tells us this.
  635. *
  636. * Return value is the adjusted value of `addr', having become an
  637. * offset from the symbol rather than the section. Should always be
  638. * zero when returning from an exact call.
  639. *
  640. * Limitation: if you define two symbols at the same place,
  641. * confusion will occur.
  642. *
  643. * Inefficiency: we search, currently, using a linked list which
  644. * isn't even necessarily sorted.
  645. */
  646. static int64_t elf_add_gsym_reloc(struct elf_section *sect,
  647. int32_t segment, uint64_t offset,
  648. int64_t pcrel, int type, bool exact)
  649. {
  650. struct elf_reloc *r;
  651. struct elf_section *s;
  652. struct elf_symbol *sym;
  653. struct rbtree *srb;
  654. int i;
  655. /*
  656. * First look up the segment/offset pair and find a global
  657. * symbol corresponding to it. If it's not one of our segments,
  658. * then it must be an external symbol, in which case we're fine
  659. * doing a normal elf_add_reloc after first sanity-checking
  660. * that the offset from the symbol is zero.
  661. */
  662. s = NULL;
  663. for (i = 0; i < nsects; i++)
  664. if (segment == sects[i]->index) {
  665. s = sects[i];
  666. break;
  667. }
  668. if (!s) {
  669. if (exact && offset)
  670. nasm_error(ERR_NONFATAL, "invalid access to an external symbol");
  671. else
  672. elf_add_reloc(sect, segment, offset - pcrel, type);
  673. return 0;
  674. }
  675. srb = rb_search(s->gsyms, offset);
  676. if (!srb || (exact && srb->key != offset)) {
  677. nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol"
  678. " for this reference");
  679. return 0;
  680. }
  681. sym = container_of(srb, struct elf_symbol, symv);
  682. r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
  683. sect->tail = &r->next;
  684. r->next = NULL;
  685. r->address = sect->len;
  686. r->offset = offset - pcrel - sym->symv.key;
  687. r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
  688. r->type = type;
  689. sect->nrelocs++;
  690. return r->offset;
  691. }
  692. static void elf32_out(int32_t segto, const void *data,
  693. enum out_type type, uint64_t size,
  694. int32_t segment, int32_t wrt)
  695. {
  696. struct elf_section *s;
  697. int64_t addr;
  698. int reltype, bytes;
  699. int i;
  700. static struct symlininfo sinfo;
  701. /*
  702. * handle absolute-assembly (structure definitions)
  703. */
  704. if (segto == NO_SEG) {
  705. if (type != OUT_RESERVE)
  706. nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  707. " space");
  708. return;
  709. }
  710. s = NULL;
  711. for (i = 0; i < nsects; i++)
  712. if (segto == sects[i]->index) {
  713. s = sects[i];
  714. break;
  715. }
  716. if (!s) {
  717. int tempint; /* ignored */
  718. if (segto != elf_section_names(".text", 2, &tempint))
  719. nasm_panic(0, "strange segment conditions in ELF driver");
  720. else {
  721. s = sects[nsects - 1];
  722. i = nsects - 1;
  723. }
  724. }
  725. /* again some stabs debugging stuff */
  726. sinfo.offset = s->len;
  727. sinfo.section = i;
  728. sinfo.segto = segto;
  729. sinfo.name = s->name;
  730. dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
  731. /* end of debugging stuff */
  732. if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
  733. nasm_error(ERR_WARNING, "attempt to initialize memory in"
  734. " BSS section `%s': ignored", s->name);
  735. s->len += realsize(type, size);
  736. return;
  737. }
  738. switch (type) {
  739. case OUT_RESERVE:
  740. if (s->type == SHT_PROGBITS) {
  741. nasm_error(ERR_WARNING, "uninitialized space declared in"
  742. " non-BSS section `%s': zeroing", s->name);
  743. elf_sect_write(s, NULL, size);
  744. } else
  745. s->len += size;
  746. break;
  747. case OUT_RAWDATA:
  748. if (segment != NO_SEG)
  749. nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
  750. elf_sect_write(s, data, size);
  751. break;
  752. case OUT_ADDRESS:
  753. {
  754. bool gnu16 = false;
  755. int asize = abs((int)size);
  756. addr = *(int64_t *)data;
  757. if (segment != NO_SEG) {
  758. if (segment % 2) {
  759. nasm_error(ERR_NONFATAL, "ELF format does not support"
  760. " segment base references");
  761. } else {
  762. if (wrt == NO_SEG) {
  763. /*
  764. * The if() is a hack to deal with compilers which
  765. * don't handle switch() statements with 64-bit
  766. * expressions.
  767. */
  768. switch (asize) {
  769. case 1:
  770. gnu16 = true;
  771. elf_add_reloc(s, segment, 0, R_386_8);
  772. break;
  773. case 2:
  774. gnu16 = true;
  775. elf_add_reloc(s, segment, 0, R_386_16);
  776. break;
  777. case 4:
  778. elf_add_reloc(s, segment, 0, R_386_32);
  779. break;
  780. default: /* Error issued further down */
  781. break;
  782. }
  783. } else if (wrt == elf_gotpc_sect + 1) {
  784. /*
  785. * The user will supply GOT relative to $$. ELF
  786. * will let us have GOT relative to $. So we
  787. * need to fix up the data item by $-$$.
  788. */
  789. addr += s->len;
  790. elf_add_reloc(s, segment, 0, R_386_GOTPC);
  791. } else if (wrt == elf_gotoff_sect + 1) {
  792. elf_add_reloc(s, segment, 0, R_386_GOTOFF);
  793. } else if (wrt == elf_tlsie_sect + 1) {
  794. addr = elf_add_gsym_reloc(s, segment, addr, 0,
  795. R_386_TLS_IE, true);
  796. } else if (wrt == elf_got_sect + 1) {
  797. addr = elf_add_gsym_reloc(s, segment, addr, 0,
  798. R_386_GOT32, true);
  799. } else if (wrt == elf_sym_sect + 1) {
  800. switch (asize) {
  801. case 1:
  802. gnu16 = true;
  803. addr = elf_add_gsym_reloc(s, segment, addr, 0,
  804. R_386_8, false);
  805. break;
  806. case 2:
  807. gnu16 = true;
  808. addr = elf_add_gsym_reloc(s, segment, addr, 0,
  809. R_386_16, false);
  810. break;
  811. case 4:
  812. addr = elf_add_gsym_reloc(s, segment, addr, 0,
  813. R_386_32, false);
  814. break;
  815. default:
  816. break;
  817. }
  818. } else if (wrt == elf_plt_sect + 1) {
  819. nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
  820. "relative PLT references");
  821. } else {
  822. nasm_error(ERR_NONFATAL, "ELF format does not support this"
  823. " use of WRT");
  824. wrt = NO_SEG; /* we can at least _try_ to continue */
  825. }
  826. }
  827. }
  828. if (gnu16) {
  829. nasm_error(ERR_WARNING | WARN_GNUELF,
  830. "8- or 16-bit relocations in ELF32 is a GNU extension");
  831. } else if (asize != 4 && segment != NO_SEG) {
  832. nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation");
  833. }
  834. elf_sect_writeaddr(s, addr, asize);
  835. break;
  836. }
  837. case OUT_REL1ADR:
  838. reltype = R_386_PC8;
  839. bytes = 1;
  840. goto rel12adr;
  841. case OUT_REL2ADR:
  842. reltype = R_386_PC16;
  843. bytes = 2;
  844. goto rel12adr;
  845. rel12adr:
  846. addr = *(int64_t *)data - size;
  847. nasm_assert(segment != segto);
  848. if (segment != NO_SEG && segment % 2) {
  849. nasm_error(ERR_NONFATAL, "ELF format does not support"
  850. " segment base references");
  851. } else {
  852. if (wrt == NO_SEG) {
  853. nasm_error(ERR_WARNING | WARN_GNUELF,
  854. "8- or 16-bit relocations in ELF is a GNU extension");
  855. elf_add_reloc(s, segment, 0, reltype);
  856. } else {
  857. nasm_error(ERR_NONFATAL,
  858. "Unsupported non-32-bit ELF relocation");
  859. }
  860. }
  861. elf_sect_writeaddr(s, addr, bytes);
  862. break;
  863. case OUT_REL4ADR:
  864. addr = *(int64_t *)data - size;
  865. if (segment == segto)
  866. nasm_panic(0, "intra-segment OUT_REL4ADR");
  867. if (segment != NO_SEG && segment % 2) {
  868. nasm_error(ERR_NONFATAL, "ELF format does not support"
  869. " segment base references");
  870. } else {
  871. if (wrt == NO_SEG) {
  872. elf_add_reloc(s, segment, 0, R_386_PC32);
  873. } else if (wrt == elf_plt_sect + 1) {
  874. elf_add_reloc(s, segment, 0, R_386_PLT32);
  875. } else if (wrt == elf_gotpc_sect + 1 ||
  876. wrt == elf_gotoff_sect + 1 ||
  877. wrt == elf_got_sect + 1) {
  878. nasm_error(ERR_NONFATAL, "ELF format cannot produce PC-"
  879. "relative GOT references");
  880. } else {
  881. nasm_error(ERR_NONFATAL, "ELF format does not support this"
  882. " use of WRT");
  883. wrt = NO_SEG; /* we can at least _try_ to continue */
  884. }
  885. }
  886. elf_sect_writeaddr(s, addr, 4);
  887. break;
  888. case OUT_REL8ADR:
  889. nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations");
  890. addr = 0;
  891. elf_sect_writeaddr(s, addr, 8);
  892. break;
  893. default:
  894. panic();
  895. }
  896. }
  897. static void elf64_out(int32_t segto, const void *data,
  898. enum out_type type, uint64_t size,
  899. int32_t segment, int32_t wrt)
  900. {
  901. struct elf_section *s;
  902. int64_t addr;
  903. int reltype, bytes;
  904. int i;
  905. static struct symlininfo sinfo;
  906. /*
  907. * handle absolute-assembly (structure definitions)
  908. */
  909. if (segto == NO_SEG) {
  910. if (type != OUT_RESERVE)
  911. nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  912. " space");
  913. return;
  914. }
  915. s = NULL;
  916. for (i = 0; i < nsects; i++)
  917. if (segto == sects[i]->index) {
  918. s = sects[i];
  919. break;
  920. }
  921. if (!s) {
  922. int tempint; /* ignored */
  923. if (segto != elf_section_names(".text", 2, &tempint))
  924. nasm_panic(0, "strange segment conditions in ELF driver");
  925. else {
  926. s = sects[nsects - 1];
  927. i = nsects - 1;
  928. }
  929. }
  930. /* again some stabs debugging stuff */
  931. sinfo.offset = s->len;
  932. sinfo.section = i;
  933. sinfo.segto = segto;
  934. sinfo.name = s->name;
  935. dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
  936. /* end of debugging stuff */
  937. if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
  938. nasm_error(ERR_WARNING, "attempt to initialize memory in"
  939. " BSS section `%s': ignored", s->name);
  940. s->len += realsize(type, size);
  941. return;
  942. }
  943. switch (type) {
  944. case OUT_RESERVE:
  945. if (s->type == SHT_PROGBITS) {
  946. nasm_error(ERR_WARNING, "uninitialized space declared in"
  947. " non-BSS section `%s': zeroing", s->name);
  948. elf_sect_write(s, NULL, size);
  949. } else
  950. s->len += size;
  951. break;
  952. case OUT_RAWDATA:
  953. if (segment != NO_SEG)
  954. nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
  955. elf_sect_write(s, data, size);
  956. break;
  957. case OUT_ADDRESS:
  958. {
  959. int isize = (int)size;
  960. int asize = abs((int)size);
  961. addr = *(int64_t *)data;
  962. if (segment == NO_SEG) {
  963. /* Do nothing */
  964. } else if (segment % 2) {
  965. nasm_error(ERR_NONFATAL, "ELF format does not support"
  966. " segment base references");
  967. } else {
  968. if (wrt == NO_SEG) {
  969. switch (isize) {
  970. case 1:
  971. case -1:
  972. elf_add_reloc(s, segment, addr, R_X86_64_8);
  973. break;
  974. case 2:
  975. case -2:
  976. elf_add_reloc(s, segment, addr, R_X86_64_16);
  977. break;
  978. case 4:
  979. elf_add_reloc(s, segment, addr, R_X86_64_32);
  980. break;
  981. case -4:
  982. elf_add_reloc(s, segment, addr, R_X86_64_32S);
  983. break;
  984. case 8:
  985. case -8:
  986. elf_add_reloc(s, segment, addr, R_X86_64_64);
  987. break;
  988. default:
  989. nasm_panic(0, "internal error elf64-hpa-871");
  990. break;
  991. }
  992. addr = 0;
  993. } else if (wrt == elf_gotpc_sect + 1) {
  994. /*
  995. * The user will supply GOT relative to $$. ELF
  996. * will let us have GOT relative to $. So we
  997. * need to fix up the data item by $-$$.
  998. */
  999. addr += s->len;
  1000. elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
  1001. addr = 0;
  1002. } else if (wrt == elf_gotoff_sect + 1) {
  1003. if (asize != 8) {
  1004. nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff "
  1005. "references to be qword");
  1006. } else {
  1007. elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
  1008. addr = 0;
  1009. }
  1010. } else if (wrt == elf_got_sect + 1) {
  1011. switch (asize) {
  1012. case 4:
  1013. elf_add_gsym_reloc(s, segment, addr, 0,
  1014. R_X86_64_GOT32, true);
  1015. addr = 0;
  1016. break;
  1017. case 8:
  1018. elf_add_gsym_reloc(s, segment, addr, 0,
  1019. R_X86_64_GOT64, true);
  1020. addr = 0;
  1021. break;
  1022. default:
  1023. nasm_error(ERR_NONFATAL, "invalid ..got reference");
  1024. break;
  1025. }
  1026. } else if (wrt == elf_sym_sect + 1) {
  1027. switch (isize) {
  1028. case 1:
  1029. case -1:
  1030. elf_add_gsym_reloc(s, segment, addr, 0,
  1031. R_X86_64_8, false);
  1032. addr = 0;
  1033. break;
  1034. case 2:
  1035. case -2:
  1036. elf_add_gsym_reloc(s, segment, addr, 0,
  1037. R_X86_64_16, false);
  1038. addr = 0;
  1039. break;
  1040. case 4:
  1041. elf_add_gsym_reloc(s, segment, addr, 0,
  1042. R_X86_64_32, false);
  1043. addr = 0;
  1044. break;
  1045. case -4:
  1046. elf_add_gsym_reloc(s, segment, addr, 0,
  1047. R_X86_64_32S, false);
  1048. addr = 0;
  1049. break;
  1050. case 8:
  1051. case -8:
  1052. elf_add_gsym_reloc(s, segment, addr, 0,
  1053. R_X86_64_64, false);
  1054. addr = 0;
  1055. break;
  1056. default:
  1057. nasm_panic(0, "internal error elf64-hpa-903");
  1058. break;
  1059. }
  1060. } else if (wrt == elf_plt_sect + 1) {
  1061. nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
  1062. "relative PLT references");
  1063. } else {
  1064. nasm_error(ERR_NONFATAL, "ELF format does not support this"
  1065. " use of WRT");
  1066. }
  1067. }
  1068. elf_sect_writeaddr(s, addr, asize);
  1069. break;
  1070. }
  1071. case OUT_REL1ADR:
  1072. reltype = R_X86_64_PC8;
  1073. bytes = 1;
  1074. goto rel12adr;
  1075. case OUT_REL2ADR:
  1076. reltype = R_X86_64_PC16;
  1077. bytes = 2;
  1078. goto rel12adr;
  1079. rel12adr:
  1080. addr = *(int64_t *)data - size;
  1081. if (segment == segto)
  1082. nasm_panic(0, "intra-segment OUT_REL1ADR");
  1083. if (segment == NO_SEG) {
  1084. /* Do nothing */
  1085. } else if (segment % 2) {
  1086. nasm_error(ERR_NONFATAL, "ELF format does not support"
  1087. " segment base references");
  1088. } else {
  1089. if (wrt == NO_SEG) {
  1090. elf_add_reloc(s, segment, addr, reltype);
  1091. addr = 0;
  1092. } else {
  1093. nasm_error(ERR_NONFATAL,
  1094. "Unsupported non-32-bit ELF relocation");
  1095. }
  1096. }
  1097. elf_sect_writeaddr(s, addr, bytes);
  1098. break;
  1099. case OUT_REL4ADR:
  1100. addr = *(int64_t *)data - size;
  1101. if (segment == segto)
  1102. nasm_panic(0, "intra-segment OUT_REL4ADR");
  1103. if (segment == NO_SEG) {
  1104. /* Do nothing */
  1105. } else if (segment % 2) {
  1106. nasm_error(ERR_NONFATAL, "ELF64 format does not support"
  1107. " segment base references");
  1108. } else {
  1109. if (wrt == NO_SEG) {
  1110. elf_add_reloc(s, segment, addr, R_X86_64_PC32);
  1111. addr = 0;
  1112. } else if (wrt == elf_plt_sect + 1) {
  1113. elf_add_gsym_reloc(s, segment, addr+size, size,
  1114. R_X86_64_PLT32, true);
  1115. addr = 0;
  1116. } else if (wrt == elf_gotpc_sect + 1 ||
  1117. wrt == elf_got_sect + 1) {
  1118. elf_add_gsym_reloc(s, segment, addr+size, size,
  1119. R_X86_64_GOTPCREL, true);
  1120. addr = 0;
  1121. } else if (wrt == elf_gotoff_sect + 1 ||
  1122. wrt == elf_got_sect + 1) {
  1123. nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
  1124. "qword absolute");
  1125. } else if (wrt == elf_gottpoff_sect + 1) {
  1126. elf_add_gsym_reloc(s, segment, addr+size, size,
  1127. R_X86_64_GOTTPOFF, true);
  1128. addr = 0;
  1129. } else {
  1130. nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
  1131. " use of WRT");
  1132. }
  1133. }
  1134. elf_sect_writeaddr(s, addr, 4);
  1135. break;
  1136. case OUT_REL8ADR:
  1137. addr = *(int64_t *)data - size;
  1138. if (segment == segto)
  1139. nasm_panic(0, "intra-segment OUT_REL8ADR");
  1140. if (segment == NO_SEG) {
  1141. /* Do nothing */
  1142. } else if (segment % 2) {
  1143. nasm_error(ERR_NONFATAL, "ELF64 format does not support"
  1144. " segment base references");
  1145. } else {
  1146. if (wrt == NO_SEG) {
  1147. elf_add_reloc(s, segment, addr, R_X86_64_PC64);
  1148. addr = 0;
  1149. } else if (wrt == elf_gotpc_sect + 1 ||
  1150. wrt == elf_got_sect + 1) {
  1151. elf_add_gsym_reloc(s, segment, addr+size, size,
  1152. R_X86_64_GOTPCREL64, true);
  1153. addr = 0;
  1154. } else if (wrt == elf_gotoff_sect + 1 ||
  1155. wrt == elf_got_sect + 1) {
  1156. nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
  1157. "absolute");
  1158. } else if (wrt == elf_gottpoff_sect + 1) {
  1159. nasm_error(ERR_NONFATAL, "ELF64 requires ..gottpoff references to be "
  1160. "dword");
  1161. } else {
  1162. nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
  1163. " use of WRT");
  1164. }
  1165. }
  1166. elf_sect_writeaddr(s, addr, 8);
  1167. break;
  1168. default:
  1169. panic();
  1170. }
  1171. }
  1172. static void elfx32_out(int32_t segto, const void *data,
  1173. enum out_type type, uint64_t size,
  1174. int32_t segment, int32_t wrt)
  1175. {
  1176. struct elf_section *s;
  1177. int64_t addr;
  1178. int reltype, bytes;
  1179. int i;
  1180. static struct symlininfo sinfo;
  1181. /*
  1182. * handle absolute-assembly (structure definitions)
  1183. */
  1184. if (segto == NO_SEG) {
  1185. if (type != OUT_RESERVE)
  1186. nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
  1187. " space");
  1188. return;
  1189. }
  1190. s = NULL;
  1191. for (i = 0; i < nsects; i++)
  1192. if (segto == sects[i]->index) {
  1193. s = sects[i];
  1194. break;
  1195. }
  1196. if (!s) {
  1197. int tempint; /* ignored */
  1198. if (segto != elf_section_names(".text", 2, &tempint))
  1199. nasm_panic(0, "strange segment conditions in ELF driver");
  1200. else {
  1201. s = sects[nsects - 1];
  1202. i = nsects - 1;
  1203. }
  1204. }
  1205. /* again some stabs debugging stuff */
  1206. sinfo.offset = s->len;
  1207. sinfo.section = i;
  1208. sinfo.segto = segto;
  1209. sinfo.name = s->name;
  1210. dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
  1211. /* end of debugging stuff */
  1212. if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
  1213. nasm_error(ERR_WARNING, "attempt to initialize memory in"
  1214. " BSS section `%s': ignored", s->name);
  1215. s->len += realsize(type, size);
  1216. return;
  1217. }
  1218. switch (type) {
  1219. case OUT_RESERVE:
  1220. if (s->type == SHT_PROGBITS) {
  1221. nasm_error(ERR_WARNING, "uninitialized space declared in"
  1222. " non-BSS section `%s': zeroing", s->name);
  1223. elf_sect_write(s, NULL, size);
  1224. } else
  1225. s->len += size;
  1226. break;
  1227. case OUT_RAWDATA:
  1228. if (segment != NO_SEG)
  1229. nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
  1230. elf_sect_write(s, data, size);
  1231. break;
  1232. case OUT_ADDRESS:
  1233. {
  1234. int isize = (int)size;
  1235. int asize = abs((int)size);
  1236. addr = *(int64_t *)data;
  1237. if (segment == NO_SEG) {
  1238. /* Do nothing */
  1239. } else if (segment % 2) {
  1240. nasm_error(ERR_NONFATAL, "ELF format does not support"
  1241. " segment base references");
  1242. } else {
  1243. if (wrt == NO_SEG) {
  1244. switch (isize) {
  1245. case 1:
  1246. case -1:
  1247. elf_add_reloc(s, segment, addr, R_X86_64_8);
  1248. break;
  1249. case 2:
  1250. case -2:
  1251. elf_add_reloc(s, segment, addr, R_X86_64_16);
  1252. break;
  1253. case 4:
  1254. elf_add_reloc(s, segment, addr, R_X86_64_32);
  1255. break;
  1256. case -4:
  1257. elf_add_reloc(s, segment, addr, R_X86_64_32S);
  1258. break;
  1259. case 8:
  1260. case -8:
  1261. elf_add_reloc(s, segment, addr, R_X86_64_64);
  1262. break;
  1263. default:
  1264. nasm_panic(0, "internal error elfx32-hpa-871");
  1265. break;
  1266. }
  1267. addr = 0;
  1268. } else if (wrt == elf_gotpc_sect + 1) {
  1269. /*
  1270. * The user will supply GOT relative to $$. ELF
  1271. * will let us have GOT relative to $. So we
  1272. * need to fix up the data item by $-$$.
  1273. */
  1274. addr += s->len;
  1275. elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
  1276. addr = 0;
  1277. } else if (wrt == elf_gotoff_sect + 1) {
  1278. nasm_error(ERR_NONFATAL, "ELFX32 doesn't support "
  1279. "R_X86_64_GOTOFF64");
  1280. } else if (wrt == elf_got_sect + 1) {
  1281. switch (asize) {
  1282. case 4:
  1283. elf_add_gsym_reloc(s, segment, addr, 0,
  1284. R_X86_64_GOT32, true);
  1285. addr = 0;
  1286. break;
  1287. default:
  1288. nasm_error(ERR_NONFATAL, "invalid ..got reference");
  1289. break;
  1290. }
  1291. } else if (wrt == elf_sym_sect + 1) {
  1292. switch (isize) {
  1293. case 1:
  1294. case -1:
  1295. elf_add_gsym_reloc(s, segment, addr, 0,
  1296. R_X86_64_8, false);
  1297. addr = 0;
  1298. break;
  1299. case 2:
  1300. case -2:
  1301. elf_add_gsym_reloc(s, segment, addr, 0,
  1302. R_X86_64_16, false);
  1303. addr = 0;
  1304. break;
  1305. case 4:
  1306. elf_add_gsym_reloc(s, segment, addr, 0,
  1307. R_X86_64_32, false);
  1308. addr = 0;
  1309. break;
  1310. case -4:
  1311. elf_add_gsym_reloc(s, segment, addr, 0,
  1312. R_X86_64_32S, false);
  1313. addr = 0;
  1314. break;
  1315. case 8:
  1316. case -8:
  1317. elf_add_gsym_reloc(s, segment, addr, 0,
  1318. R_X86_64_64, false);
  1319. addr = 0;
  1320. break;
  1321. default:
  1322. nasm_panic(0, "internal error elfx32-hpa-903");
  1323. break;
  1324. }
  1325. } else if (wrt == elf_plt_sect + 1) {
  1326. nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
  1327. "relative PLT references");
  1328. } else {
  1329. nasm_error(ERR_NONFATAL, "ELF format does not support this"
  1330. " use of WRT");
  1331. }
  1332. }
  1333. elf_sect_writeaddr(s, addr, asize);
  1334. break;
  1335. }
  1336. case OUT_REL1ADR:
  1337. reltype = R_X86_64_PC8;
  1338. bytes = 1;
  1339. goto rel12adr;
  1340. case OUT_REL2ADR:
  1341. reltype = R_X86_64_PC16;
  1342. bytes = 2;
  1343. goto rel12adr;
  1344. rel12adr:
  1345. addr = *(int64_t *)data - size;
  1346. if (segment == segto)
  1347. nasm_panic(0, "intra-segment OUT_REL1ADR");
  1348. if (segment == NO_SEG) {
  1349. /* Do nothing */
  1350. } else if (segment % 2) {
  1351. nasm_error(ERR_NONFATAL, "ELF format does not support"
  1352. " segment base references");
  1353. } else {
  1354. if (wrt == NO_SEG) {
  1355. elf_add_reloc(s, segment, addr, reltype);
  1356. addr = 0;
  1357. } else {
  1358. nasm_error(ERR_NONFATAL,
  1359. "Unsupported non-32-bit ELF relocation");
  1360. }
  1361. }
  1362. elf_sect_writeaddr(s, addr, bytes);
  1363. break;
  1364. case OUT_REL4ADR:
  1365. addr = *(int64_t *)data - size;
  1366. if (segment == segto)
  1367. nasm_panic(0, "intra-segment OUT_REL4ADR");
  1368. if (segment == NO_SEG) {
  1369. /* Do nothing */
  1370. } else if (segment % 2) {
  1371. nasm_error(ERR_NONFATAL, "ELFX32 format does not support"
  1372. " segment base references");
  1373. } else {
  1374. if (wrt == NO_SEG) {
  1375. elf_add_reloc(s, segment, addr, R_X86_64_PC32);
  1376. addr = 0;
  1377. } else if (wrt == elf_plt_sect + 1) {
  1378. elf_add_gsym_reloc(s, segment, addr+size, size,
  1379. R_X86_64_PLT32, true);
  1380. addr = 0;
  1381. } else if (wrt == elf_gotpc_sect + 1 ||
  1382. wrt == elf_got_sect + 1) {
  1383. elf_add_gsym_reloc(s, segment, addr+size, size,
  1384. R_X86_64_GOTPCREL, true);
  1385. addr = 0;
  1386. } else if (wrt == elf_gotoff_sect + 1 ||
  1387. wrt == elf_got_sect + 1) {
  1388. nasm_error(ERR_NONFATAL, "invalid ..gotoff reference");
  1389. } else if (wrt == elf_gottpoff_sect + 1) {
  1390. elf_add_gsym_reloc(s, segment, addr+size, size,
  1391. R_X86_64_GOTTPOFF, true);
  1392. addr = 0;
  1393. } else {
  1394. nasm_error(ERR_NONFATAL, "ELFX32 format does not support this"
  1395. " use of WRT");
  1396. }
  1397. }
  1398. elf_sect_writeaddr(s, addr, 4);
  1399. break;
  1400. case OUT_REL8ADR:
  1401. nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations");
  1402. addr = 0;
  1403. elf_sect_writeaddr(s, addr, 8);
  1404. break;
  1405. default:
  1406. panic();
  1407. }
  1408. }
  1409. static void elf_write(void)
  1410. {
  1411. int align;
  1412. char *p;
  1413. int i;
  1414. struct SAA *symtab;
  1415. int32_t symtablen, symtablocal;
  1416. /*
  1417. * Work out how many sections we will have. We have SHN_UNDEF,
  1418. * then the flexible user sections, then the fixed sections
  1419. * `.shstrtab', `.symtab' and `.strtab', then optionally
  1420. * relocation sections for the user sections.
  1421. */
  1422. nsections = sec_numspecial + 1;
  1423. if (dfmt_is_stabs())
  1424. nsections += 3;
  1425. else if (dfmt_is_dwarf())
  1426. nsections += 10;
  1427. add_sectname("", ".shstrtab");
  1428. add_sectname("", ".symtab");
  1429. add_sectname("", ".strtab");
  1430. for (i = 0; i < nsects; i++) {
  1431. nsections++; /* for the section itself */
  1432. if (sects[i]->head) {
  1433. nsections++; /* for its relocations */
  1434. add_sectname(is_elf32() ? ".rel" : ".rela", sects[i]->name);
  1435. }
  1436. }
  1437. if (dfmt_is_stabs()) {
  1438. /* in case the debug information is wanted, just add these three sections... */
  1439. add_sectname("", ".stab");
  1440. add_sectname("", ".stabstr");
  1441. add_sectname(is_elf32() ? ".rel" : ".rela", ".stab");
  1442. } else if (dfmt_is_dwarf()) {
  1443. /* the dwarf debug standard specifies the following ten sections,
  1444. not all of which are currently implemented,
  1445. although all of them are defined. */
  1446. #define debug_aranges (int64_t) (nsections-10)
  1447. #define debug_info (int64_t) (nsections-7)
  1448. #define debug_abbrev (int64_t) (nsections-5)
  1449. #define debug_line (int64_t) (nsections-4)
  1450. add_sectname("", ".debug_aranges");
  1451. add_sectname(".rela", ".debug_aranges");
  1452. add_sectname("", ".debug_pubnames");
  1453. add_sectname("", ".debug_info");
  1454. add_sectname(".rela", ".debug_info");
  1455. add_sectname("", ".debug_abbrev");
  1456. add_sectname("", ".debug_line");
  1457. add_sectname(".rela", ".debug_line");
  1458. add_sectname("", ".debug_frame");
  1459. add_sectname("", ".debug_loc");
  1460. }
  1461. /*
  1462. * Output the ELF header.
  1463. */
  1464. if (is_elf32() || is_elfx32()) {
  1465. Elf32_Ehdr ehdr;
  1466. nasm_zero(ehdr.e_ident);
  1467. memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
  1468. ehdr.e_ident[EI_CLASS] = ELFCLASS32;
  1469. ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
  1470. ehdr.e_ident[EI_VERSION] = EV_CURRENT;
  1471. ehdr.e_ident[EI_OSABI] = elf_osabi;
  1472. ehdr.e_ident[EI_ABIVERSION] = elf_abiver;
  1473. ehdr.e_type = cpu_to_le16(ET_REL);
  1474. ehdr.e_machine = cpu_to_le16(is_elf32() ? EM_386 : EM_X86_64);
  1475. ehdr.e_version = cpu_to_le16(EV_CURRENT);
  1476. ehdr.e_entry = 0;
  1477. ehdr.e_phoff = 0;
  1478. ehdr.e_shoff = sizeof(Elf64_Ehdr);
  1479. ehdr.e_flags = 0;
  1480. ehdr.e_ehsize = cpu_to_le16(sizeof(Elf32_Ehdr));
  1481. ehdr.e_phentsize = 0;
  1482. ehdr.e_phnum = 0;
  1483. ehdr.e_shentsize = cpu_to_le16(sizeof(Elf32_Shdr));
  1484. ehdr.e_shnum = cpu_to_le16(nsections);
  1485. ehdr.e_shstrndx = cpu_to_le16(sec_shstrtab);
  1486. nasm_write(&ehdr, sizeof(ehdr), ofile);
  1487. fwritezero(sizeof(Elf64_Ehdr) - sizeof(Elf32_Ehdr), ofile);
  1488. } else {
  1489. Elf64_Ehdr ehdr;
  1490. nasm_assert(is_elf64());
  1491. nasm_zero(ehdr.e_ident);
  1492. memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
  1493. ehdr.e_ident[EI_CLASS] = ELFCLASS64;
  1494. ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
  1495. ehdr.e_ident[EI_VERSION] = EV_CURRENT;
  1496. ehdr.e_ident[EI_OSABI] = elf_osabi;
  1497. ehdr.e_ident[EI_ABIVERSION] = elf_abiver;
  1498. ehdr.e_type = cpu_to_le16(ET_REL);
  1499. ehdr.e_machine = cpu_to_le16(EM_X86_64);
  1500. ehdr.e_version = cpu_to_le16(EV_CURRENT);
  1501. ehdr.e_entry = 0;
  1502. ehdr.e_phoff = 0;
  1503. ehdr.e_shoff = sizeof(Elf64_Ehdr);
  1504. ehdr.e_flags = 0;
  1505. ehdr.e_ehsize = cpu_to_le16(sizeof(Elf64_Ehdr));
  1506. ehdr.e_phentsize = 0;
  1507. ehdr.e_phnum = 0;
  1508. ehdr.e_shentsize = cpu_to_le16(sizeof(Elf64_Shdr));
  1509. ehdr.e_shnum = cpu_to_le16(nsections);
  1510. ehdr.e_shstrndx = cpu_to_le16(sec_shstrtab);
  1511. nasm_write(&ehdr, sizeof(ehdr), ofile);
  1512. }
  1513. /*
  1514. * Build the symbol table and relocation tables.
  1515. */
  1516. symtab = elf_build_symtab(&symtablen, &symtablocal);
  1517. for (i = 0; i < nsects; i++)
  1518. if (sects[i]->head)
  1519. sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
  1520. sects[i]->head);
  1521. /*
  1522. * Now output the section header table.
  1523. */
  1524. elf_foffs = sizeof(Elf64_Ehdr) + (is_elf64() ? sizeof(Elf64_Shdr): sizeof(Elf32_Shdr)) * nsections;
  1525. align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
  1526. elf_foffs += align;
  1527. elf_nsect = 0;
  1528. elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
  1529. /* SHN_UNDEF */
  1530. elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
  1531. p = shstrtab + 1;
  1532. /* The normal sections */
  1533. for (i = 0; i < nsects; i++) {
  1534. elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
  1535. (sects[i]->type == SHT_PROGBITS ?
  1536. sects[i]->data : NULL), true,
  1537. sects[i]->len, 0, 0, sects[i]->align, 0);
  1538. p += strlen(p) + 1;
  1539. }
  1540. /* .shstrtab */
  1541. elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
  1542. shstrtablen, 0, 0, 1, 0);
  1543. p += strlen(p) + 1;
  1544. /* .symtab */
  1545. if (is_elf64())
  1546. elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
  1547. symtablen, sec_strtab, symtablocal, 8, 24);
  1548. else
  1549. elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
  1550. symtablen, sec_strtab, symtablocal, 4, 16);
  1551. p += strlen(p) + 1;
  1552. /* .strtab */
  1553. elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
  1554. strslen, 0, 0, 1, 0);
  1555. p += strlen(p) + 1;
  1556. /* The relocation sections */
  1557. if (is_elf32()) {
  1558. for (i = 0; i < nsects; i++) {
  1559. if (sects[i]->head) {
  1560. elf_section_header(p - shstrtab, SHT_REL, 0, sects[i]->rel, true,
  1561. sects[i]->rellen, sec_symtab, i + 1, 4, 8);
  1562. p += strlen(p) + 1;
  1563. }
  1564. }
  1565. } else if (is_elfx32()) {
  1566. for (i = 0; i < nsects; i++) {
  1567. if (sects[i]->head) {
  1568. elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
  1569. sects[i]->rellen, sec_symtab, i + 1, 4, 12);
  1570. p += strlen(p) + 1;
  1571. }
  1572. }
  1573. } else {
  1574. nasm_assert(is_elf64());
  1575. for (i = 0; i < nsects; i++) {
  1576. if (sects[i]->head) {
  1577. elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
  1578. sects[i]->rellen, sec_symtab, i + 1, 8, 24);
  1579. p += strlen(p) + 1;
  1580. }
  1581. }
  1582. }
  1583. if (dfmt_is_stabs()) {
  1584. /* for debugging information, create the last three sections
  1585. which are the .stab , .stabstr and .rel.stab sections respectively */
  1586. /* this function call creates the stab sections in memory */
  1587. stabs_generate();
  1588. if (stabbuf && stabstrbuf && stabrelbuf) {
  1589. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
  1590. stablen, sec_stabstr, 0, 4, 12);
  1591. p += strlen(p) + 1;
  1592. elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
  1593. stabstrlen, 0, 0, 4, 0);
  1594. p += strlen(p) + 1;
  1595. /* link -> symtable info -> section to refer to */
  1596. if (is_elf32()) {
  1597. elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
  1598. stabrellen, sec_symtab, sec_stab, 4, 8);
  1599. } else {
  1600. elf_section_header(p - shstrtab, SHT_RELA, 0, stabrelbuf, false,
  1601. stabrellen, sec_symtab, sec_stab, 4, is_elf64() ? 24 : 12);
  1602. }
  1603. p += strlen(p) + 1;
  1604. }
  1605. } else if (dfmt_is_dwarf()) {
  1606. /* for dwarf debugging information, create the ten dwarf sections */
  1607. /* this function call creates the dwarf sections in memory */
  1608. if (dwarf_fsect)
  1609. dwarf_generate();
  1610. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
  1611. arangeslen, 0, 0, 1, 0);
  1612. p += strlen(p) + 1;
  1613. elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
  1614. arangesrellen, sec_symtab,
  1615. is_elf64() ? debug_aranges : sec_debug_aranges,
  1616. 1, is_elf64() ? 24 : 12);
  1617. p += strlen(p) + 1;
  1618. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
  1619. false, pubnameslen, 0, 0, 1, 0);
  1620. p += strlen(p) + 1;
  1621. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
  1622. infolen, 0, 0, 1, 0);
  1623. p += strlen(p) + 1;
  1624. elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
  1625. inforellen, sec_symtab,
  1626. is_elf64() ? debug_info : sec_debug_info,
  1627. 1, is_elf64() ? 24 : 12);
  1628. p += strlen(p) + 1;
  1629. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
  1630. abbrevlen, 0, 0, 1, 0);
  1631. p += strlen(p) + 1;
  1632. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
  1633. linelen, 0, 0, 1, 0);
  1634. p += strlen(p) + 1;
  1635. elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
  1636. linerellen, sec_symtab,
  1637. is_elf64() ? debug_line : sec_debug_line,
  1638. 1, is_elf64() ? 24 : 12);
  1639. p += strlen(p) + 1;
  1640. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
  1641. framelen, 0, 0, 8, 0);
  1642. p += strlen(p) + 1;
  1643. elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
  1644. loclen, 0, 0, 1, 0);
  1645. p += strlen(p) + 1;
  1646. }
  1647. fwritezero(align, ofile);
  1648. /*
  1649. * Now output the sections.
  1650. */
  1651. elf_write_sections();
  1652. nasm_free(elf_sects);
  1653. saa_free(symtab);
  1654. }
  1655. static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
  1656. {
  1657. struct SAA *s = saa_init(1L);
  1658. struct elf_symbol *sym;
  1659. int i;
  1660. size_t usize = is_elf64() ? sizeof(Elf64_Sym) : sizeof(Elf32_Sym);
  1661. union {
  1662. Elf32_Sym sym32;
  1663. Elf64_Sym sym64;
  1664. } u;
  1665. *len = *local = 0;
  1666. /*
  1667. * Zero symbol first as required by spec.
  1668. */
  1669. saa_wbytes(s, NULL, usize);
  1670. *len += usize;
  1671. (*local)++;
  1672. /*
  1673. * Next, an entry for the file name.
  1674. */
  1675. if (is_elf64()) {
  1676. u.sym64.st_name = cpu_to_le32(1);
  1677. u.sym64.st_info = ELF64_ST_INFO(STB_LOCAL, STT_FILE);
  1678. u.sym64.st_other = 0;
  1679. u.sym64.st_shndx = cpu_to_le16(SHN_ABS);
  1680. u.sym64.st_value = 0;
  1681. u.sym64.st_size = 0;
  1682. } else {
  1683. u.sym32.st_name = cpu_to_le32(1);
  1684. u.sym32.st_value = 0;
  1685. u.sym32.st_size = 0;
  1686. u.sym32.st_info = ELF32_ST_INFO(STB_LOCAL, STT_FILE);
  1687. u.sym32.st_other = 0;
  1688. u.sym32.st_shndx = cpu_to_le16(SHN_ABS);
  1689. }
  1690. saa_wbytes(s, &u, usize);
  1691. *len += usize;
  1692. (*local)++;
  1693. /*
  1694. * Now some standard symbols defining the segments, for relocation
  1695. * purposes.
  1696. */
  1697. if (is_elf64()) {
  1698. u.sym64.st_name = 0;
  1699. u.sym64.st_other = 0;
  1700. u.sym64.st_value = 0;
  1701. u.sym64.st_size = 0;
  1702. for (i = 1; i <= nsects; i++) {
  1703. u.sym64.st_info = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
  1704. u.sym64.st_shndx = cpu_to_le16(i);
  1705. saa_wbytes(s, &u, usize);
  1706. *len += usize;
  1707. (*local)++;
  1708. }
  1709. } else {
  1710. u.sym32.st_name = 0;
  1711. u.sym32.st_value = 0;
  1712. u.sym32.st_size = 0;
  1713. u.sym32.st_other = 0;
  1714. for (i = 1; i <= nsects; i++) {
  1715. u.sym32.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
  1716. u.sym32.st_shndx = cpu_to_le16(i);
  1717. saa_wbytes(s, &u, usize);
  1718. *len += usize;
  1719. (*local)++;
  1720. }
  1721. }
  1722. /*
  1723. * Now the other local symbols.
  1724. */
  1725. saa_rewind(syms);
  1726. if (is_elf64()) {
  1727. while ((sym = saa_rstruct(syms))) {
  1728. if (sym->type & SYM_GLOBAL)
  1729. continue;
  1730. u.sym64.st_name = cpu_to_le32(sym->strpos);
  1731. u.sym64.st_info = sym->type;
  1732. u.sym64.st_other = sym->other;
  1733. u.sym64.st_shndx = cpu_to_le16(sym->section);
  1734. u.sym64.st_value = cpu_to_le64(sym->symv.key);
  1735. u.sym64.st_size = cpu_to_le64(sym->size);
  1736. saa_wbytes(s, &u, usize);
  1737. *len += usize;
  1738. (*local)++;
  1739. }
  1740. /*
  1741. * dwarf needs symbols for debug sections
  1742. * which are relocation targets.
  1743. */
  1744. if (dfmt_is_dwarf()) {
  1745. dwarf_infosym = *local;
  1746. u.sym64.st_name = 0;
  1747. u.sym64.st_info = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
  1748. u.sym64.st_other = 0;
  1749. u.sym64.st_shndx = cpu_to_le16(debug_info);
  1750. u.sym64.st_value = 0;
  1751. u.sym64.st_size = 0;
  1752. saa_wbytes(s, &u, usize);
  1753. *len += usize;
  1754. (*local)++;
  1755. dwarf_abbrevsym = *local;
  1756. u.sym64.st_name = 0;
  1757. u.sym64.st_info = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
  1758. u.sym64.st_other = 0;
  1759. u.sym64.st_shndx = cpu_to_le16(debug_abbrev);
  1760. u.sym64.st_value = 0;
  1761. u.sym64.st_size = 0;
  1762. saa_wbytes(s, &u, usize);
  1763. *len += usize;
  1764. (*local)++;
  1765. dwarf_linesym = *local;
  1766. u.sym64.st_name = 0;
  1767. u.sym64.st_info = ELF64_ST_INFO(STB_LOCAL, STT_SECTION);
  1768. u.sym64.st_other = 0;
  1769. u.sym64.st_shndx = cpu_to_le16(debug_line);
  1770. u.sym64.st_value = 0;
  1771. u.sym64.st_size = 0;
  1772. saa_wbytes(s, &u, usize);
  1773. *len += usize;
  1774. (*local)++;
  1775. }
  1776. } else {
  1777. while ((sym = saa_rstruct(syms))) {
  1778. if (sym->type & SYM_GLOBAL)
  1779. continue;
  1780. u.sym32.st_name = cpu_to_le32(sym->strpos);
  1781. u.sym32.st_value = cpu_to_le32(sym->symv.key);
  1782. u.sym32.st_size = cpu_to_le32(sym->size);
  1783. u.sym32.st_info = sym->type;
  1784. u.sym32.st_other = sym->other;
  1785. u.sym32.st_shndx = cpu_to_le16(sym->section);
  1786. saa_wbytes(s, &u, usize);
  1787. *len += usize;
  1788. (*local)++;
  1789. }
  1790. /*
  1791. * dwarf needs symbols for debug sections
  1792. * which are relocation targets.
  1793. */
  1794. if (dfmt_is_dwarf()) {
  1795. dwarf_infosym = *local;
  1796. u.sym32.st_name = 0;
  1797. u.sym32.st_value = 0;
  1798. u.sym32.st_size = 0;
  1799. u.sym32.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
  1800. u.sym32.st_other = 0;
  1801. u.sym32.st_shndx = cpu_to_le16(sec_debug_info);
  1802. saa_wbytes(s, &u, usize);
  1803. *len += usize;
  1804. (*local)++;
  1805. dwarf_abbrevsym = *local;
  1806. u.sym32.st_name = 0;
  1807. u.sym32.st_value = 0;
  1808. u.sym32.st_size = 0;
  1809. u.sym32.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
  1810. u.sym32.st_other = 0;
  1811. u.sym32.st_shndx = cpu_to_le16(sec_debug_abbrev);
  1812. saa_wbytes(s, &u, usize);
  1813. *len += usize;
  1814. (*local)++;
  1815. dwarf_linesym = *local;
  1816. u.sym32.st_name = 0;
  1817. u.sym32.st_value = 0;
  1818. u.sym32.st_size = 0;
  1819. u.sym32.st_info = ELF32_ST_INFO(STB_LOCAL, STT_SECTION);
  1820. u.sym32.st_other = 0;
  1821. u.sym32.st_shndx = cpu_to_le16(sec_debug_line);
  1822. saa_wbytes(s, &u, usize);
  1823. *len += usize;
  1824. (*local)++;
  1825. }
  1826. }
  1827. /*
  1828. * Now the global symbols.
  1829. */
  1830. saa_rewind(syms);
  1831. if (is_elf64()) {
  1832. while ((sym = saa_rstruct(syms))) {
  1833. if (!(sym->type & SYM_GLOBAL))
  1834. continue;
  1835. u.sym64.st_name = cpu_to_le32(sym->strpos);
  1836. u.sym64.st_info = sym->type;
  1837. u.sym64.st_other = sym->other;
  1838. u.sym64.st_shndx = cpu_to_le16(sym->section);
  1839. u.sym64.st_value = cpu_to_le64(sym->symv.key);
  1840. u.sym64.st_size = cpu_to_le64(sym->size);
  1841. saa_wbytes(s, &u, usize);
  1842. *len += usize;
  1843. }
  1844. } else {
  1845. while ((sym = saa_rstruct(syms))) {
  1846. if (!(sym->type & SYM_GLOBAL))
  1847. continue;
  1848. u.sym32.st_name = cpu_to_le32(sym->strpos);
  1849. u.sym32.st_value = cpu_to_le32(sym->symv.key);
  1850. u.sym32.st_size = cpu_to_le32(sym->size);
  1851. u.sym32.st_info = sym->type;
  1852. u.sym32.st_other = sym->other;
  1853. u.sym32.st_shndx = cpu_to_le16(sym->section);
  1854. saa_wbytes(s, &u, usize);
  1855. *len += usize;
  1856. }
  1857. }
  1858. return s;
  1859. }
  1860. static struct SAA *elf_build_reltab(uint64_t *len, struct elf_reloc *r)
  1861. {
  1862. struct SAA *s;
  1863. int32_t global_offset;
  1864. size_t usize = is_elf64() ? sizeof(Elf64_Rela) :
  1865. (is_elfx32() ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel));
  1866. union {
  1867. Elf32_Rel rel32;
  1868. Elf32_Rela rela32;
  1869. Elf64_Rela rela64;
  1870. } u;
  1871. if (!r)
  1872. return NULL;
  1873. s = saa_init(1L);
  1874. *len = 0;
  1875. /*
  1876. * How to onvert from a global placeholder to a real symbol index;
  1877. * the +2 refers to the two special entries, the null entry and
  1878. * the filename entry.
  1879. */
  1880. global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
  1881. if (is_elf32()) {
  1882. while (r) {
  1883. int32_t sym = r->symbol;
  1884. if (sym >= GLOBAL_TEMP_BASE)
  1885. sym += global_offset;
  1886. u.rel32.r_offset = cpu_to_le32(r->address);
  1887. u.rel32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
  1888. saa_wbytes(s, &u, usize);
  1889. *len += usize;
  1890. r = r->next;
  1891. }
  1892. } else if (is_elfx32()) {
  1893. while (r) {
  1894. int32_t sym = r->symbol;
  1895. if (sym >= GLOBAL_TEMP_BASE)
  1896. sym += global_offset;
  1897. u.rela32.r_offset = cpu_to_le32(r->address);
  1898. u.rela32.r_info = cpu_to_le32(ELF32_R_INFO(sym, r->type));
  1899. u.rela32.r_addend = cpu_to_le32(r->offset);
  1900. saa_wbytes(s, &u, usize);
  1901. *len += usize;
  1902. r = r->next;
  1903. }
  1904. } else {
  1905. nasm_assert(is_elf64());
  1906. while (r) {
  1907. int32_t sym = r->symbol;
  1908. if (sym >= GLOBAL_TEMP_BASE)
  1909. sym += global_offset;
  1910. u.rela64.r_offset = cpu_to_le64(r->address);
  1911. u.rela64.r_info = cpu_to_le64(ELF64_R_INFO(sym, r->type));
  1912. u.rela64.r_addend = cpu_to_le64(r->offset);
  1913. saa_wbytes(s, &u, usize);
  1914. *len += usize;
  1915. r = r->next;
  1916. }
  1917. }
  1918. return s;
  1919. }
  1920. static void elf_section_header(int name, int type, uint64_t flags,
  1921. void *data, bool is_saa, uint64_t datalen,
  1922. int link, int info, int align, int eltsize)
  1923. {
  1924. union {
  1925. Elf32_Shdr shdr32;
  1926. Elf64_Shdr shdr64;
  1927. } shdr;
  1928. elf_sects[elf_nsect].data = data;
  1929. elf_sects[elf_nsect].len = datalen;
  1930. elf_sects[elf_nsect].is_saa = is_saa;
  1931. elf_nsect++;
  1932. if (is_elf32() || is_elfx32()) {
  1933. shdr.shdr32.sh_name = cpu_to_le32(name);
  1934. shdr.shdr32.sh_type = cpu_to_le32(type);
  1935. shdr.shdr32.sh_flags = cpu_to_le32(flags);
  1936. shdr.shdr32.sh_addr = 0;
  1937. shdr.shdr32.sh_offset = cpu_to_le32(type == SHT_NULL ? 0 : elf_foffs);
  1938. shdr.shdr32.sh_size = cpu_to_le32(datalen);
  1939. if (data)
  1940. elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
  1941. shdr.shdr32.sh_link = cpu_to_le32(link);
  1942. shdr.shdr32.sh_info = cpu_to_le32(info);
  1943. shdr.shdr32.sh_addralign = cpu_to_le32(align);
  1944. shdr.shdr32.sh_entsize = cpu_to_le32(eltsize);
  1945. } else {
  1946. nasm_assert(is_elf64());
  1947. shdr.shdr64.sh_name = cpu_to_le32(name);
  1948. shdr.shdr64.sh_type = cpu_to_le32(type);
  1949. shdr.shdr64.sh_flags = cpu_to_le64(flags);
  1950. shdr.shdr64.sh_addr = 0;
  1951. shdr.shdr64.sh_offset = cpu_to_le64(type == SHT_NULL ? 0 : elf_foffs);
  1952. shdr.shdr64.sh_size = cpu_to_le32(datalen);
  1953. if (data)
  1954. elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
  1955. shdr.shdr64.sh_link = cpu_to_le32(link);
  1956. shdr.shdr64.sh_info = cpu_to_le32(info);
  1957. shdr.shdr64.sh_addralign = cpu_to_le64(align);
  1958. shdr.shdr64.sh_entsize = cpu_to_le64(eltsize);
  1959. }
  1960. nasm_write(&shdr, is_elf64() ? sizeof(shdr.shdr64) : sizeof(shdr.shdr32), ofile);
  1961. }
  1962. static void elf_write_sections(void)
  1963. {
  1964. int i;
  1965. for (i = 0; i < elf_nsect; i++)
  1966. if (elf_sects[i].data) {
  1967. int32_t len = elf_sects[i].len;
  1968. int32_t reallen = ALIGN(len, SEC_FILEALIGN);
  1969. int32_t align = reallen - len;
  1970. if (elf_sects[i].is_saa)
  1971. saa_fpwrite(elf_sects[i].data, ofile);
  1972. else
  1973. nasm_write(elf_sects[i].data, len, ofile);
  1974. fwritezero(align, ofile);
  1975. }
  1976. }
  1977. static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
  1978. {
  1979. saa_wbytes(sect->data, data, len);
  1980. sect->len += len;
  1981. }
  1982. static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
  1983. {
  1984. saa_writeaddr(sect->data, data, len);
  1985. sect->len += len;
  1986. }
  1987. static void elf_sectalign(int32_t seg, unsigned int value)
  1988. {
  1989. struct elf_section *s = NULL;
  1990. int i;
  1991. for (i = 0; i < nsects; i++) {
  1992. if (sects[i]->index == seg) {
  1993. s = sects[i];
  1994. break;
  1995. }
  1996. }
  1997. if (!s || !is_power2(value))
  1998. return;
  1999. if (value > s->align)
  2000. s->align = value;
  2001. }
  2002. static int32_t elf_segbase(int32_t segment)
  2003. {
  2004. return segment;
  2005. }
  2006. extern macros_t elf_stdmac[];
  2007. /* Claim "elf" as a pragma namespace, for the future */
  2008. static const struct pragma_facility elf_pragma_list[] =
  2009. {
  2010. { "elf", NULL },
  2011. { NULL, NULL } /* Implements the canonical output name */
  2012. };
  2013. static const struct dfmt elf32_df_dwarf = {
  2014. "ELF32 (i386) dwarf debug format for Linux/Unix",
  2015. "dwarf",
  2016. dwarf_init,
  2017. dwarf_linenum,
  2018. null_debug_deflabel,
  2019. null_debug_directive,
  2020. debug_typevalue,
  2021. dwarf_output,
  2022. dwarf_cleanup,
  2023. NULL /* pragma list */
  2024. };
  2025. static const struct dfmt elf32_df_stabs = {
  2026. "ELF32 (i386) stabs debug format for Linux/Unix",
  2027. "stabs",
  2028. null_debug_init,
  2029. stabs_linenum,
  2030. null_debug_deflabel,
  2031. null_debug_directive,
  2032. debug_typevalue,
  2033. stabs_output,
  2034. stabs_cleanup,
  2035. NULL /* pragma list */
  2036. };
  2037. static const struct dfmt * const elf32_debugs_arr[3] =
  2038. { &elf32_df_dwarf, &elf32_df_stabs, NULL };
  2039. const struct ofmt of_elf32 = {
  2040. "ELF32 (i386) object files (e.g. Linux)",
  2041. "elf32",
  2042. ".o",
  2043. 0,
  2044. 32,
  2045. elf32_debugs_arr,
  2046. &elf32_df_stabs,
  2047. elf_stdmac,
  2048. elf_init,
  2049. null_reset,
  2050. nasm_do_legacy_output,
  2051. elf32_out,
  2052. elf_deflabel,
  2053. elf_section_names,
  2054. NULL,
  2055. elf_sectalign,
  2056. elf_segbase,
  2057. elf_directive,
  2058. elf_cleanup,
  2059. elf_pragma_list,
  2060. };
  2061. static const struct dfmt elf64_df_dwarf = {
  2062. "ELF64 (x86-64) dwarf debug format for Linux/Unix",
  2063. "dwarf",
  2064. dwarf_init,
  2065. dwarf_linenum,
  2066. null_debug_deflabel,
  2067. null_debug_directive,
  2068. debug_typevalue,
  2069. dwarf_output,
  2070. dwarf_cleanup,
  2071. NULL /* pragma list */
  2072. };
  2073. static const struct dfmt elf64_df_stabs = {
  2074. "ELF64 (x86-64) stabs debug format for Linux/Unix",
  2075. "stabs",
  2076. null_debug_init,
  2077. stabs_linenum,
  2078. null_debug_deflabel,
  2079. null_debug_directive,
  2080. debug_typevalue,
  2081. stabs_output,
  2082. stabs_cleanup,
  2083. NULL /* pragma list */
  2084. };
  2085. static const struct dfmt * const elf64_debugs_arr[3] =
  2086. { &elf64_df_dwarf, &elf64_df_stabs, NULL };
  2087. const struct ofmt of_elf64 = {
  2088. "ELF64 (x86_64) object files (e.g. Linux)",
  2089. "elf64",
  2090. ".o",
  2091. 0,
  2092. 64,
  2093. elf64_debugs_arr,
  2094. &elf64_df_stabs,
  2095. elf_stdmac,
  2096. elf_init,
  2097. null_reset,
  2098. nasm_do_legacy_output,
  2099. elf64_out,
  2100. elf_deflabel,
  2101. elf_section_names,
  2102. NULL,
  2103. elf_sectalign,
  2104. elf_segbase,
  2105. elf_directive,
  2106. elf_cleanup,
  2107. elf_pragma_list,
  2108. };
  2109. static const struct dfmt elfx32_df_dwarf = {
  2110. "ELFX32 (x86-64) dwarf debug format for Linux/Unix",
  2111. "dwarf",
  2112. dwarf_init,
  2113. dwarf_linenum,
  2114. null_debug_deflabel,
  2115. null_debug_directive,
  2116. debug_typevalue,
  2117. dwarf_output,
  2118. dwarf_cleanup,
  2119. NULL /* pragma list */
  2120. };
  2121. static const struct dfmt elfx32_df_stabs = {
  2122. "ELFX32 (x86-64) stabs debug format for Linux/Unix",
  2123. "stabs",
  2124. null_debug_init,
  2125. stabs_linenum,
  2126. null_debug_deflabel,
  2127. null_debug_directive,
  2128. debug_typevalue,
  2129. stabs_output,
  2130. stabs_cleanup,
  2131. elf_pragma_list,
  2132. };
  2133. static const struct dfmt * const elfx32_debugs_arr[3] =
  2134. { &elfx32_df_dwarf, &elfx32_df_stabs, NULL };
  2135. const struct ofmt of_elfx32 = {
  2136. "ELFX32 (x86_64) object files (e.g. Linux)",
  2137. "elfx32",
  2138. ".o",
  2139. 0,
  2140. 64,
  2141. elfx32_debugs_arr,
  2142. &elfx32_df_stabs,
  2143. elf_stdmac,
  2144. elf_init,
  2145. null_reset,
  2146. nasm_do_legacy_output,
  2147. elfx32_out,
  2148. elf_deflabel,
  2149. elf_section_names,
  2150. NULL,
  2151. elf_sectalign,
  2152. elf_segbase,
  2153. elf_directive,
  2154. elf_cleanup,
  2155. NULL /* pragma list */
  2156. };
  2157. static bool is_elf64(void)
  2158. {
  2159. return ofmt == &of_elf64;
  2160. }
  2161. static bool is_elf32(void)
  2162. {
  2163. return ofmt == &of_elf32;
  2164. }
  2165. static bool is_elfx32(void)
  2166. {
  2167. return ofmt == &of_elfx32;
  2168. }
  2169. static bool dfmt_is_stabs(void)
  2170. {
  2171. return dfmt == &elf32_df_stabs ||
  2172. dfmt == &elfx32_df_stabs ||
  2173. dfmt == &elf64_df_stabs;
  2174. }
  2175. static bool dfmt_is_dwarf(void)
  2176. {
  2177. return dfmt == &elf32_df_dwarf ||
  2178. dfmt == &elfx32_df_dwarf ||
  2179. dfmt == &elf64_df_dwarf;
  2180. }
  2181. /* common debugging routines */
  2182. static void debug_typevalue(int32_t type)
  2183. {
  2184. int32_t stype, ssize;
  2185. switch (TYM_TYPE(type)) {
  2186. case TY_LABEL:
  2187. ssize = 0;
  2188. stype = STT_NOTYPE;
  2189. break;
  2190. case TY_BYTE:
  2191. ssize = 1;
  2192. stype = STT_OBJECT;
  2193. break;
  2194. case TY_WORD:
  2195. ssize = 2;
  2196. stype = STT_OBJECT;
  2197. break;
  2198. case TY_DWORD:
  2199. ssize = 4;
  2200. stype = STT_OBJECT;
  2201. break;
  2202. case TY_FLOAT:
  2203. ssize = 4;
  2204. stype = STT_OBJECT;
  2205. break;
  2206. case TY_QWORD:
  2207. ssize = 8;
  2208. stype = STT_OBJECT;
  2209. break;
  2210. case TY_TBYTE:
  2211. ssize = 10;
  2212. stype = STT_OBJECT;
  2213. break;
  2214. case TY_OWORD:
  2215. ssize = 16;
  2216. stype = STT_OBJECT;
  2217. break;
  2218. case TY_YWORD:
  2219. ssize = 32;
  2220. stype = STT_OBJECT;
  2221. break;
  2222. case TY_ZWORD:
  2223. ssize = 64;
  2224. stype = STT_OBJECT;
  2225. break;
  2226. case TY_COMMON:
  2227. ssize = 0;
  2228. stype = STT_COMMON;
  2229. break;
  2230. case TY_SEG:
  2231. ssize = 0;
  2232. stype = STT_SECTION;
  2233. break;
  2234. case TY_EXTERN:
  2235. ssize = 0;
  2236. stype = STT_NOTYPE;
  2237. break;
  2238. case TY_EQU:
  2239. ssize = 0;
  2240. stype = STT_NOTYPE;
  2241. break;
  2242. default:
  2243. ssize = 0;
  2244. stype = STT_NOTYPE;
  2245. break;
  2246. }
  2247. if (stype == STT_OBJECT && lastsym && !lastsym->type) {
  2248. lastsym->size = ssize;
  2249. lastsym->type = stype;
  2250. }
  2251. }
  2252. /* stabs debugging routines */
  2253. static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
  2254. {
  2255. (void)segto;
  2256. if (!stabs_filename) {
  2257. stabs_filename = nasm_malloc(strlen(filename) + 1);
  2258. strcpy(stabs_filename, filename);
  2259. } else {
  2260. if (strcmp(stabs_filename, filename)) {
  2261. /* yep, a memory leak...this program is one-shot anyway, so who cares...
  2262. in fact, this leak comes in quite handy to maintain a list of files
  2263. encountered so far in the symbol lines... */
  2264. /* why not nasm_free(stabs_filename); we're done with the old one */
  2265. stabs_filename = nasm_malloc(strlen(filename) + 1);
  2266. strcpy(stabs_filename, filename);
  2267. }
  2268. }
  2269. debug_immcall = 1;
  2270. currentline = linenumber;
  2271. }
  2272. static void stabs_output(int type, void *param)
  2273. {
  2274. struct symlininfo *s;
  2275. struct linelist *el;
  2276. if (type == TY_DEBUGSYMLIN) {
  2277. if (debug_immcall) {
  2278. s = (struct symlininfo *)param;
  2279. if (!(sects[s->section]->flags & SHF_EXECINSTR))
  2280. return; /* line info is only collected for executable sections */
  2281. numlinestabs++;
  2282. el = nasm_malloc(sizeof(struct linelist));
  2283. el->info.offset = s->offset;
  2284. el->info.section = s->section;
  2285. el->info.name = s->name;
  2286. el->line = currentline;
  2287. el->filename = stabs_filename;
  2288. el->next = 0;
  2289. if (stabslines) {
  2290. stabslines->last->next = el;
  2291. stabslines->last = el;
  2292. } else {
  2293. stabslines = el;
  2294. stabslines->last = el;
  2295. }
  2296. }
  2297. }
  2298. debug_immcall = 0;
  2299. }
  2300. /* for creating the .stab , .stabstr and .rel.stab sections in memory */
  2301. static void stabs_generate(void)
  2302. {
  2303. int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
  2304. uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
  2305. char **allfiles;
  2306. int *fileidx;
  2307. struct linelist *ptr;
  2308. ptr = stabslines;
  2309. allfiles = nasm_zalloc(numlinestabs * sizeof(char *));
  2310. numfiles = 0;
  2311. while (ptr) {
  2312. if (numfiles == 0) {
  2313. allfiles[0] = ptr->filename;
  2314. numfiles++;
  2315. } else {
  2316. for (i = 0; i < numfiles; i++) {
  2317. if (!strcmp(allfiles[i], ptr->filename))
  2318. break;
  2319. }
  2320. if (i >= numfiles) {
  2321. allfiles[i] = ptr->filename;
  2322. numfiles++;
  2323. }
  2324. }
  2325. ptr = ptr->next;
  2326. }
  2327. strsize = 1;
  2328. fileidx = nasm_malloc(numfiles * sizeof(int));
  2329. for (i = 0; i < numfiles; i++) {
  2330. fileidx[i] = strsize;
  2331. strsize += strlen(allfiles[i]) + 1;
  2332. }
  2333. currfile = mainfileindex = 0;
  2334. for (i = 0; i < numfiles; i++) {
  2335. if (!strcmp(allfiles[i], elf_module)) {
  2336. currfile = mainfileindex = i;
  2337. break;
  2338. }
  2339. }
  2340. /*
  2341. * worst case size of the stab buffer would be:
  2342. * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
  2343. * plus one "ending" entry
  2344. */
  2345. sbuf = nasm_malloc((numlinestabs * 2 + 4) *
  2346. sizeof(struct stabentry));
  2347. ssbuf = nasm_malloc(strsize);
  2348. rbuf = nasm_malloc(numlinestabs * (is_elf64() ? 16 : 8) * (2 + 3));
  2349. rptr = rbuf;
  2350. for (i = 0; i < numfiles; i++)
  2351. strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
  2352. ssbuf[0] = 0;
  2353. stabstrlen = strsize; /* set global variable for length of stab strings */
  2354. sptr = sbuf;
  2355. ptr = stabslines;
  2356. numstabs = 0;
  2357. if (ptr) {
  2358. /*
  2359. * this is the first stab, its strx points to the filename of the
  2360. * the source-file, the n_desc field should be set to the number
  2361. * of remaining stabs
  2362. */
  2363. WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
  2364. /* this is the stab for the main source file */
  2365. WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
  2366. /* relocation table entry */
  2367. /*
  2368. * Since the symbol table has two entries before
  2369. * the section symbols, the index in the info.section
  2370. * member must be adjusted by adding 2
  2371. */
  2372. if (is_elf32()) {
  2373. WRITELONG(rptr, (sptr - sbuf) - 4);
  2374. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
  2375. } else if (is_elfx32()) {
  2376. WRITELONG(rptr, (sptr - sbuf) - 4);
  2377. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
  2378. WRITELONG(rptr, 0);
  2379. } else {
  2380. nasm_assert(is_elf64());
  2381. WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
  2382. WRITELONG(rptr, R_X86_64_32);
  2383. WRITELONG(rptr, ptr->info.section + 2);
  2384. WRITEDLONG(rptr, 0);
  2385. }
  2386. numstabs++;
  2387. }
  2388. if (is_elf32()) {
  2389. while (ptr) {
  2390. if (strcmp(allfiles[currfile], ptr->filename)) {
  2391. /* oops file has changed... */
  2392. for (i = 0; i < numfiles; i++)
  2393. if (!strcmp(allfiles[i], ptr->filename))
  2394. break;
  2395. currfile = i;
  2396. WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
  2397. ptr->info.offset);
  2398. numstabs++;
  2399. /* relocation table entry */
  2400. WRITELONG(rptr, (sptr - sbuf) - 4);
  2401. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
  2402. }
  2403. WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
  2404. numstabs++;
  2405. /* relocation table entry */
  2406. WRITELONG(rptr, (sptr - sbuf) - 4);
  2407. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
  2408. ptr = ptr->next;
  2409. }
  2410. } else if (is_elfx32()) {
  2411. while (ptr) {
  2412. if (strcmp(allfiles[currfile], ptr->filename)) {
  2413. /* oops file has changed... */
  2414. for (i = 0; i < numfiles; i++)
  2415. if (!strcmp(allfiles[i], ptr->filename))
  2416. break;
  2417. currfile = i;
  2418. WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
  2419. ptr->info.offset);
  2420. numstabs++;
  2421. /* relocation table entry */
  2422. WRITELONG(rptr, (sptr - sbuf) - 4);
  2423. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
  2424. WRITELONG(rptr, ptr->info.offset);
  2425. }
  2426. WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
  2427. numstabs++;
  2428. /* relocation table entry */
  2429. WRITELONG(rptr, (sptr - sbuf) - 4);
  2430. WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
  2431. WRITELONG(rptr, ptr->info.offset);
  2432. ptr = ptr->next;
  2433. }
  2434. } else {
  2435. nasm_assert(is_elf64());
  2436. while (ptr) {
  2437. if (strcmp(allfiles[currfile], ptr->filename)) {
  2438. /* oops file has changed... */
  2439. for (i = 0; i < numfiles; i++)
  2440. if (!strcmp(allfiles[i], ptr->filename))
  2441. break;
  2442. currfile = i;
  2443. WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
  2444. ptr->info.offset);
  2445. numstabs++;
  2446. /* relocation table entry */
  2447. WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
  2448. WRITELONG(rptr, R_X86_64_32);
  2449. WRITELONG(rptr, ptr->info.section + 2);
  2450. WRITEDLONG(rptr, ptr->info.offset);
  2451. }
  2452. WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
  2453. numstabs++;
  2454. /* relocation table entry */
  2455. WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
  2456. WRITELONG(rptr, R_X86_64_32);
  2457. WRITELONG(rptr, ptr->info.section + 2);
  2458. WRITEDLONG(rptr, ptr->info.offset);
  2459. ptr = ptr->next;
  2460. }
  2461. }
  2462. /* this is an "ending" token */
  2463. WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
  2464. numstabs++;
  2465. ((struct stabentry *)sbuf)->n_desc = numstabs;
  2466. nasm_free(allfiles);
  2467. nasm_free(fileidx);
  2468. stablen = (sptr - sbuf);
  2469. stabrellen = (rptr - rbuf);
  2470. stabrelbuf = rbuf;
  2471. stabbuf = sbuf;
  2472. stabstrbuf = ssbuf;
  2473. }
  2474. static void stabs_cleanup(void)
  2475. {
  2476. struct linelist *ptr, *del;
  2477. if (!stabslines)
  2478. return;
  2479. ptr = stabslines;
  2480. while (ptr) {
  2481. del = ptr;
  2482. ptr = ptr->next;
  2483. nasm_free(del);
  2484. }
  2485. nasm_free(stabbuf);
  2486. nasm_free(stabrelbuf);
  2487. nasm_free(stabstrbuf);
  2488. }
  2489. /* dwarf routines */
  2490. static void dwarf_init(void)
  2491. {
  2492. ndebugs = 3; /* 3 debug symbols */
  2493. }
  2494. static void dwarf_linenum(const char *filename, int32_t linenumber,
  2495. int32_t segto)
  2496. {
  2497. (void)segto;
  2498. dwarf_findfile(filename);
  2499. debug_immcall = 1;
  2500. currentline = linenumber;
  2501. }
  2502. /* called from elf_out with type == TY_DEBUGSYMLIN */
  2503. static void dwarf_output(int type, void *param)
  2504. {
  2505. int ln, aa, inx, maxln, soc;
  2506. struct symlininfo *s;
  2507. struct SAA *plinep;
  2508. (void)type;
  2509. s = (struct symlininfo *)param;
  2510. /* line number info is only gathered for executable sections */
  2511. if (!(sects[s->section]->flags & SHF_EXECINSTR))
  2512. return;
  2513. /* Check if section index has changed */
  2514. if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
  2515. dwarf_findsect(s->section);
  2516. /* do nothing unless line or file has changed */
  2517. if (!debug_immcall)
  2518. return;
  2519. ln = currentline - dwarf_csect->line;
  2520. aa = s->offset - dwarf_csect->offset;
  2521. inx = dwarf_clist->line;
  2522. plinep = dwarf_csect->psaa;
  2523. /* check for file change */
  2524. if (!(inx == dwarf_csect->file)) {
  2525. saa_write8(plinep,DW_LNS_set_file);
  2526. saa_write8(plinep,inx);
  2527. dwarf_csect->file = inx;
  2528. }
  2529. /* check for line change */
  2530. if (ln) {
  2531. /* test if in range of special op code */
  2532. maxln = line_base + line_range;
  2533. soc = (ln - line_base) + (line_range * aa) + opcode_base;
  2534. if (ln >= line_base && ln < maxln && soc < 256) {
  2535. saa_write8(plinep,soc);
  2536. } else {
  2537. saa_write8(plinep,DW_LNS_advance_line);
  2538. saa_wleb128s(plinep,ln);
  2539. if (aa) {
  2540. saa_write8(plinep,DW_LNS_advance_pc);
  2541. saa_wleb128u(plinep,aa);
  2542. }
  2543. saa_write8(plinep,DW_LNS_copy);
  2544. }
  2545. dwarf_csect->line = currentline;
  2546. dwarf_csect->offset = s->offset;
  2547. }
  2548. /* show change handled */
  2549. debug_immcall = 0;
  2550. }
  2551. static void dwarf_generate(void)
  2552. {
  2553. uint8_t *pbuf;
  2554. int indx;
  2555. struct linelist *ftentry;
  2556. struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
  2557. struct SAA *parangesrel, *plinesrel, *pinforel;
  2558. struct sectlist *psect;
  2559. size_t saalen, linepoff, totlen, highaddr;
  2560. if (is_elf32()) {
  2561. /* write epilogues for each line program range */
  2562. /* and build aranges section */
  2563. paranges = saa_init(1L);
  2564. parangesrel = saa_init(1L);
  2565. saa_write16(paranges,2); /* dwarf version */
  2566. saa_write32(parangesrel, paranges->datalen+4);
  2567. saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */
  2568. saa_write32(parangesrel, 0);
  2569. saa_write32(paranges,0); /* offset into info */
  2570. saa_write8(paranges,4); /* pointer size */
  2571. saa_write8(paranges,0); /* not segmented */
  2572. saa_write32(paranges,0); /* padding */
  2573. /* iterate though sectlist entries */
  2574. psect = dwarf_fsect;
  2575. totlen = 0;
  2576. highaddr = 0;
  2577. for (indx = 0; indx < dwarf_nsections; indx++) {
  2578. plinep = psect->psaa;
  2579. /* Line Number Program Epilogue */
  2580. saa_write8(plinep,2); /* std op 2 */
  2581. saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
  2582. saa_write8(plinep,DW_LNS_extended_op);
  2583. saa_write8(plinep,1); /* operand length */
  2584. saa_write8(plinep,DW_LNE_end_sequence);
  2585. totlen += plinep->datalen;
  2586. /* range table relocation entry */
  2587. saa_write32(parangesrel, paranges->datalen + 4);
  2588. saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
  2589. saa_write32(parangesrel, (uint32_t) 0);
  2590. /* range table entry */
  2591. saa_write32(paranges,0x0000); /* range start */
  2592. saa_write32(paranges,sects[psect->section]->len); /* range length */
  2593. highaddr += sects[psect->section]->len;
  2594. /* done with this entry */
  2595. psect = psect->next;
  2596. }
  2597. saa_write32(paranges,0); /* null address */
  2598. saa_write32(paranges,0); /* null length */
  2599. saalen = paranges->datalen;
  2600. arangeslen = saalen + 4;
  2601. arangesbuf = pbuf = nasm_malloc(arangeslen);
  2602. WRITELONG(pbuf,saalen); /* initial length */
  2603. saa_rnbytes(paranges, pbuf, saalen);
  2604. saa_free(paranges);
  2605. } else if (is_elfx32()) {
  2606. /* write epilogues for each line program range */
  2607. /* and build aranges section */
  2608. paranges = saa_init(1L);
  2609. parangesrel = saa_init(1L);
  2610. saa_write16(paranges,3); /* dwarf version */
  2611. saa_write32(parangesrel, paranges->datalen+4);
  2612. saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */
  2613. saa_write32(parangesrel, 0);
  2614. saa_write32(paranges,0); /* offset into info */
  2615. saa_write8(paranges,4); /* pointer size */
  2616. saa_write8(paranges,0); /* not segmented */
  2617. saa_write32(paranges,0); /* padding */
  2618. /* iterate though sectlist entries */
  2619. psect = dwarf_fsect;
  2620. totlen = 0;
  2621. highaddr = 0;
  2622. for (indx = 0; indx < dwarf_nsections; indx++) {
  2623. plinep = psect->psaa;
  2624. /* Line Number Program Epilogue */
  2625. saa_write8(plinep,2); /* std op 2 */
  2626. saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
  2627. saa_write8(plinep,DW_LNS_extended_op);
  2628. saa_write8(plinep,1); /* operand length */
  2629. saa_write8(plinep,DW_LNE_end_sequence);
  2630. totlen += plinep->datalen;
  2631. /* range table relocation entry */
  2632. saa_write32(parangesrel, paranges->datalen + 4);
  2633. saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_X86_64_32);
  2634. saa_write32(parangesrel, (uint32_t) 0);
  2635. /* range table entry */
  2636. saa_write32(paranges,0x0000); /* range start */
  2637. saa_write32(paranges,sects[psect->section]->len); /* range length */
  2638. highaddr += sects[psect->section]->len;
  2639. /* done with this entry */
  2640. psect = psect->next;
  2641. }
  2642. saa_write32(paranges,0); /* null address */
  2643. saa_write32(paranges,0); /* null length */
  2644. saalen = paranges->datalen;
  2645. arangeslen = saalen + 4;
  2646. arangesbuf = pbuf = nasm_malloc(arangeslen);
  2647. WRITELONG(pbuf,saalen); /* initial length */
  2648. saa_rnbytes(paranges, pbuf, saalen);
  2649. saa_free(paranges);
  2650. } else {
  2651. nasm_assert(is_elf64());
  2652. /* write epilogues for each line program range */
  2653. /* and build aranges section */
  2654. paranges = saa_init(1L);
  2655. parangesrel = saa_init(1L);
  2656. saa_write16(paranges,3); /* dwarf version */
  2657. saa_write64(parangesrel, paranges->datalen+4);
  2658. saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
  2659. saa_write64(parangesrel, 0);
  2660. saa_write32(paranges,0); /* offset into info */
  2661. saa_write8(paranges,8); /* pointer size */
  2662. saa_write8(paranges,0); /* not segmented */
  2663. saa_write32(paranges,0); /* padding */
  2664. /* iterate though sectlist entries */
  2665. psect = dwarf_fsect;
  2666. totlen = 0;
  2667. highaddr = 0;
  2668. for (indx = 0; indx < dwarf_nsections; indx++) {
  2669. plinep = psect->psaa;
  2670. /* Line Number Program Epilogue */
  2671. saa_write8(plinep,2); /* std op 2 */
  2672. saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
  2673. saa_write8(plinep,DW_LNS_extended_op);
  2674. saa_write8(plinep,1); /* operand length */
  2675. saa_write8(plinep,DW_LNE_end_sequence);
  2676. totlen += plinep->datalen;
  2677. /* range table relocation entry */
  2678. saa_write64(parangesrel, paranges->datalen + 4);
  2679. saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
  2680. saa_write64(parangesrel, (uint64_t) 0);
  2681. /* range table entry */
  2682. saa_write64(paranges,0x0000); /* range start */
  2683. saa_write64(paranges,sects[psect->section]->len); /* range length */
  2684. highaddr += sects[psect->section]->len;
  2685. /* done with this entry */
  2686. psect = psect->next;
  2687. }
  2688. saa_write64(paranges,0); /* null address */
  2689. saa_write64(paranges,0); /* null length */
  2690. saalen = paranges->datalen;
  2691. arangeslen = saalen + 4;
  2692. arangesbuf = pbuf = nasm_malloc(arangeslen);
  2693. WRITELONG(pbuf,saalen); /* initial length */
  2694. saa_rnbytes(paranges, pbuf, saalen);
  2695. saa_free(paranges);
  2696. }
  2697. /* build rela.aranges section */
  2698. arangesrellen = saalen = parangesrel->datalen;
  2699. arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
  2700. saa_rnbytes(parangesrel, pbuf, saalen);
  2701. saa_free(parangesrel);
  2702. /* build pubnames section */
  2703. ppubnames = saa_init(1L);
  2704. saa_write16(ppubnames,3); /* dwarf version */
  2705. saa_write32(ppubnames,0); /* offset into info */
  2706. saa_write32(ppubnames,0); /* space used in info */
  2707. saa_write32(ppubnames,0); /* end of list */
  2708. saalen = ppubnames->datalen;
  2709. pubnameslen = saalen + 4;
  2710. pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
  2711. WRITELONG(pbuf,saalen); /* initial length */
  2712. saa_rnbytes(ppubnames, pbuf, saalen);
  2713. saa_free(ppubnames);
  2714. if (is_elf32()) {
  2715. /* build info section */
  2716. pinfo = saa_init(1L);
  2717. pinforel = saa_init(1L);
  2718. saa_write16(pinfo,2); /* dwarf version */
  2719. saa_write32(pinforel, pinfo->datalen + 4);
  2720. saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */
  2721. saa_write32(pinforel, 0);
  2722. saa_write32(pinfo,0); /* offset into abbrev */
  2723. saa_write8(pinfo,4); /* pointer size */
  2724. saa_write8(pinfo,1); /* abbrviation number LEB128u */
  2725. saa_write32(pinforel, pinfo->datalen + 4);
  2726. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
  2727. saa_write32(pinforel, 0);
  2728. saa_write32(pinfo,0); /* DW_AT_low_pc */
  2729. saa_write32(pinforel, pinfo->datalen + 4);
  2730. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
  2731. saa_write32(pinforel, 0);
  2732. saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
  2733. saa_write32(pinforel, pinfo->datalen + 4);
  2734. saa_write32(pinforel, (dwarf_linesym << 8) + R_386_32); /* reloc to line */
  2735. saa_write32(pinforel, 0);
  2736. saa_write32(pinfo,0); /* DW_AT_stmt_list */
  2737. saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
  2738. saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
  2739. saa_write16(pinfo,DW_LANG_Mips_Assembler);
  2740. saa_write8(pinfo,2); /* abbrviation number LEB128u */
  2741. saa_write32(pinforel, pinfo->datalen + 4);
  2742. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
  2743. saa_write32(pinforel, 0);
  2744. saa_write32(pinfo,0); /* DW_AT_low_pc */
  2745. saa_write32(pinfo,0); /* DW_AT_frame_base */
  2746. saa_write8(pinfo,0); /* end of entries */
  2747. saalen = pinfo->datalen;
  2748. infolen = saalen + 4;
  2749. infobuf = pbuf = nasm_malloc(infolen);
  2750. WRITELONG(pbuf,saalen); /* initial length */
  2751. saa_rnbytes(pinfo, pbuf, saalen);
  2752. saa_free(pinfo);
  2753. } else if (is_elfx32()) {
  2754. /* build info section */
  2755. pinfo = saa_init(1L);
  2756. pinforel = saa_init(1L);
  2757. saa_write16(pinfo,3); /* dwarf version */
  2758. saa_write32(pinforel, pinfo->datalen + 4);
  2759. saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */
  2760. saa_write32(pinforel, 0);
  2761. saa_write32(pinfo,0); /* offset into abbrev */
  2762. saa_write8(pinfo,4); /* pointer size */
  2763. saa_write8(pinfo,1); /* abbrviation number LEB128u */
  2764. saa_write32(pinforel, pinfo->datalen + 4);
  2765. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
  2766. saa_write32(pinforel, 0);
  2767. saa_write32(pinfo,0); /* DW_AT_low_pc */
  2768. saa_write32(pinforel, pinfo->datalen + 4);
  2769. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
  2770. saa_write32(pinforel, 0);
  2771. saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
  2772. saa_write32(pinforel, pinfo->datalen + 4);
  2773. saa_write32(pinforel, (dwarf_linesym << 8) + R_X86_64_32); /* reloc to line */
  2774. saa_write32(pinforel, 0);
  2775. saa_write32(pinfo,0); /* DW_AT_stmt_list */
  2776. saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
  2777. saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
  2778. saa_write16(pinfo,DW_LANG_Mips_Assembler);
  2779. saa_write8(pinfo,2); /* abbrviation number LEB128u */
  2780. saa_write32(pinforel, pinfo->datalen + 4);
  2781. saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
  2782. saa_write32(pinforel, 0);
  2783. saa_write32(pinfo,0); /* DW_AT_low_pc */
  2784. saa_write32(pinfo,0); /* DW_AT_frame_base */
  2785. saa_write8(pinfo,0); /* end of entries */
  2786. saalen = pinfo->datalen;
  2787. infolen = saalen + 4;
  2788. infobuf = pbuf = nasm_malloc(infolen);
  2789. WRITELONG(pbuf,saalen); /* initial length */
  2790. saa_rnbytes(pinfo, pbuf, saalen);
  2791. saa_free(pinfo);
  2792. } else {
  2793. nasm_assert(is_elf64());
  2794. /* build info section */
  2795. pinfo = saa_init(1L);
  2796. pinforel = saa_init(1L);
  2797. saa_write16(pinfo,3); /* dwarf version */
  2798. saa_write64(pinforel, pinfo->datalen + 4);
  2799. saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
  2800. saa_write64(pinforel, 0);
  2801. saa_write32(pinfo,0); /* offset into abbrev */
  2802. saa_write8(pinfo,8); /* pointer size */
  2803. saa_write8(pinfo,1); /* abbrviation number LEB128u */
  2804. saa_write64(pinforel, pinfo->datalen + 4);
  2805. saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
  2806. saa_write64(pinforel, 0);
  2807. saa_write64(pinfo,0); /* DW_AT_low_pc */
  2808. saa_write64(pinforel, pinfo->datalen + 4);
  2809. saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
  2810. saa_write64(pinforel, 0);
  2811. saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
  2812. saa_write64(pinforel, pinfo->datalen + 4);
  2813. saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
  2814. saa_write64(pinforel, 0);
  2815. saa_write32(pinfo,0); /* DW_AT_stmt_list */
  2816. saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
  2817. saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
  2818. saa_write16(pinfo,DW_LANG_Mips_Assembler);
  2819. saa_write8(pinfo,2); /* abbrviation number LEB128u */
  2820. saa_write64(pinforel, pinfo->datalen + 4);
  2821. saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
  2822. saa_write64(pinforel, 0);
  2823. saa_write64(pinfo,0); /* DW_AT_low_pc */
  2824. saa_write64(pinfo,0); /* DW_AT_frame_base */
  2825. saa_write8(pinfo,0); /* end of entries */
  2826. saalen = pinfo->datalen;
  2827. infolen = saalen + 4;
  2828. infobuf = pbuf = nasm_malloc(infolen);
  2829. WRITELONG(pbuf,saalen); /* initial length */
  2830. saa_rnbytes(pinfo, pbuf, saalen);
  2831. saa_free(pinfo);
  2832. }
  2833. /* build rela.info section */
  2834. inforellen = saalen = pinforel->datalen;
  2835. inforelbuf = pbuf = nasm_malloc(inforellen);
  2836. saa_rnbytes(pinforel, pbuf, saalen);
  2837. saa_free(pinforel);
  2838. /* build abbrev section */
  2839. pabbrev = saa_init(1L);
  2840. saa_write8(pabbrev,1); /* entry number LEB128u */
  2841. saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
  2842. saa_write8(pabbrev,1); /* has children */
  2843. /* the following attributes and forms are all LEB128u values */
  2844. saa_write8(pabbrev,DW_AT_low_pc);
  2845. saa_write8(pabbrev,DW_FORM_addr);
  2846. saa_write8(pabbrev,DW_AT_high_pc);
  2847. saa_write8(pabbrev,DW_FORM_addr);
  2848. saa_write8(pabbrev,DW_AT_stmt_list);
  2849. saa_write8(pabbrev,DW_FORM_data4);
  2850. saa_write8(pabbrev,DW_AT_name);
  2851. saa_write8(pabbrev,DW_FORM_string);
  2852. saa_write8(pabbrev,DW_AT_producer);
  2853. saa_write8(pabbrev,DW_FORM_string);
  2854. saa_write8(pabbrev,DW_AT_language);
  2855. saa_write8(pabbrev,DW_FORM_data2);
  2856. saa_write16(pabbrev,0); /* end of entry */
  2857. /* LEB128u usage same as above */
  2858. saa_write8(pabbrev,2); /* entry number */
  2859. saa_write8(pabbrev,DW_TAG_subprogram);
  2860. saa_write8(pabbrev,0); /* no children */
  2861. saa_write8(pabbrev,DW_AT_low_pc);
  2862. saa_write8(pabbrev,DW_FORM_addr);
  2863. saa_write8(pabbrev,DW_AT_frame_base);
  2864. saa_write8(pabbrev,DW_FORM_data4);
  2865. saa_write16(pabbrev,0); /* end of entry */
  2866. /* Terminal zero entry */
  2867. saa_write8(pabbrev,0);
  2868. abbrevlen = saalen = pabbrev->datalen;
  2869. abbrevbuf = pbuf = nasm_malloc(saalen);
  2870. saa_rnbytes(pabbrev, pbuf, saalen);
  2871. saa_free(pabbrev);
  2872. /* build line section */
  2873. /* prolog */
  2874. plines = saa_init(1L);
  2875. saa_write8(plines,1); /* Minimum Instruction Length */
  2876. saa_write8(plines,1); /* Initial value of 'is_stmt' */
  2877. saa_write8(plines,line_base); /* Line Base */
  2878. saa_write8(plines,line_range); /* Line Range */
  2879. saa_write8(plines,opcode_base); /* Opcode Base */
  2880. /* standard opcode lengths (# of LEB128u operands) */
  2881. saa_write8(plines,0); /* Std opcode 1 length */
  2882. saa_write8(plines,1); /* Std opcode 2 length */
  2883. saa_write8(plines,1); /* Std opcode 3 length */
  2884. saa_write8(plines,1); /* Std opcode 4 length */
  2885. saa_write8(plines,1); /* Std opcode 5 length */
  2886. saa_write8(plines,0); /* Std opcode 6 length */
  2887. saa_write8(plines,0); /* Std opcode 7 length */
  2888. saa_write8(plines,0); /* Std opcode 8 length */
  2889. saa_write8(plines,1); /* Std opcode 9 length */
  2890. saa_write8(plines,0); /* Std opcode 10 length */
  2891. saa_write8(plines,0); /* Std opcode 11 length */
  2892. saa_write8(plines,1); /* Std opcode 12 length */
  2893. /* Directory Table */
  2894. saa_write8(plines,0); /* End of table */
  2895. /* File Name Table */
  2896. ftentry = dwarf_flist;
  2897. for (indx = 0; indx < dwarf_numfiles; indx++) {
  2898. saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
  2899. saa_write8(plines,0); /* directory LEB128u */
  2900. saa_write8(plines,0); /* time LEB128u */
  2901. saa_write8(plines,0); /* size LEB128u */
  2902. ftentry = ftentry->next;
  2903. }
  2904. saa_write8(plines,0); /* End of table */
  2905. linepoff = plines->datalen;
  2906. linelen = linepoff + totlen + 10;
  2907. linebuf = pbuf = nasm_malloc(linelen);
  2908. WRITELONG(pbuf,linelen-4); /* initial length */
  2909. WRITESHORT(pbuf,3); /* dwarf version */
  2910. WRITELONG(pbuf,linepoff); /* offset to line number program */
  2911. /* write line header */
  2912. saalen = linepoff;
  2913. saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
  2914. pbuf += linepoff;
  2915. saa_free(plines);
  2916. /* concatonate line program ranges */
  2917. linepoff += 13;
  2918. plinesrel = saa_init(1L);
  2919. psect = dwarf_fsect;
  2920. if (is_elf32()) {
  2921. for (indx = 0; indx < dwarf_nsections; indx++) {
  2922. saa_write32(plinesrel, linepoff);
  2923. saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
  2924. saa_write32(plinesrel, (uint32_t) 0);
  2925. plinep = psect->psaa;
  2926. saalen = plinep->datalen;
  2927. saa_rnbytes(plinep, pbuf, saalen);
  2928. pbuf += saalen;
  2929. linepoff += saalen;
  2930. saa_free(plinep);
  2931. /* done with this entry */
  2932. psect = psect->next;
  2933. }
  2934. } else if (is_elfx32()) {
  2935. for (indx = 0; indx < dwarf_nsections; indx++) {
  2936. saa_write32(plinesrel, linepoff);
  2937. saa_write32(plinesrel, ((psect->section + 2) << 8) + R_X86_64_32);
  2938. saa_write32(plinesrel, 0);
  2939. plinep = psect->psaa;
  2940. saalen = plinep->datalen;
  2941. saa_rnbytes(plinep, pbuf, saalen);
  2942. pbuf += saalen;
  2943. linepoff += saalen;
  2944. saa_free(plinep);
  2945. /* done with this entry */
  2946. psect = psect->next;
  2947. }
  2948. } else {
  2949. nasm_assert(is_elf64());
  2950. for (indx = 0; indx < dwarf_nsections; indx++) {
  2951. saa_write64(plinesrel, linepoff);
  2952. saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
  2953. saa_write64(plinesrel, (uint64_t) 0);
  2954. plinep = psect->psaa;
  2955. saalen = plinep->datalen;
  2956. saa_rnbytes(plinep, pbuf, saalen);
  2957. pbuf += saalen;
  2958. linepoff += saalen;
  2959. saa_free(plinep);
  2960. /* done with this entry */
  2961. psect = psect->next;
  2962. }
  2963. }
  2964. /* build rela.lines section */
  2965. linerellen =saalen = plinesrel->datalen;
  2966. linerelbuf = pbuf = nasm_malloc(linerellen);
  2967. saa_rnbytes(plinesrel, pbuf, saalen);
  2968. saa_free(plinesrel);
  2969. /* build frame section */
  2970. framelen = 4;
  2971. framebuf = pbuf = nasm_malloc(framelen);
  2972. WRITELONG(pbuf,framelen-4); /* initial length */
  2973. /* build loc section */
  2974. loclen = 16;
  2975. locbuf = pbuf = nasm_malloc(loclen);
  2976. if (is_elf32()) {
  2977. WRITELONG(pbuf,0); /* null beginning offset */
  2978. WRITELONG(pbuf,0); /* null ending offset */
  2979. } else if (is_elfx32()) {
  2980. WRITELONG(pbuf,0); /* null beginning offset */
  2981. WRITELONG(pbuf,0); /* null ending offset */
  2982. } else {
  2983. nasm_assert(is_elf64());
  2984. WRITEDLONG(pbuf,0); /* null beginning offset */
  2985. WRITEDLONG(pbuf,0); /* null ending offset */
  2986. }
  2987. }
  2988. static void dwarf_cleanup(void)
  2989. {
  2990. nasm_free(arangesbuf);
  2991. nasm_free(arangesrelbuf);
  2992. nasm_free(pubnamesbuf);
  2993. nasm_free(infobuf);
  2994. nasm_free(inforelbuf);
  2995. nasm_free(abbrevbuf);
  2996. nasm_free(linebuf);
  2997. nasm_free(linerelbuf);
  2998. nasm_free(framebuf);
  2999. nasm_free(locbuf);
  3000. }
  3001. static void dwarf_findfile(const char * fname)
  3002. {
  3003. int finx;
  3004. struct linelist *match;
  3005. /* return if fname is current file name */
  3006. if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
  3007. return;
  3008. /* search for match */
  3009. match = 0;
  3010. if (dwarf_flist) {
  3011. match = dwarf_flist;
  3012. for (finx = 0; finx < dwarf_numfiles; finx++) {
  3013. if (!(strcmp(fname, match->filename))) {
  3014. dwarf_clist = match;
  3015. return;
  3016. }
  3017. match = match->next;
  3018. }
  3019. }
  3020. /* add file name to end of list */
  3021. dwarf_clist = nasm_malloc(sizeof(struct linelist));
  3022. dwarf_numfiles++;
  3023. dwarf_clist->line = dwarf_numfiles;
  3024. dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
  3025. strcpy(dwarf_clist->filename,fname);
  3026. dwarf_clist->next = 0;
  3027. if (!dwarf_flist) { /* if first entry */
  3028. dwarf_flist = dwarf_elist = dwarf_clist;
  3029. dwarf_clist->last = 0;
  3030. } else { /* chain to previous entry */
  3031. dwarf_elist->next = dwarf_clist;
  3032. dwarf_elist = dwarf_clist;
  3033. }
  3034. }
  3035. static void dwarf_findsect(const int index)
  3036. {
  3037. int sinx;
  3038. struct sectlist *match;
  3039. struct SAA *plinep;
  3040. /* return if index is current section index */
  3041. if (dwarf_csect && (dwarf_csect->section == index))
  3042. return;
  3043. /* search for match */
  3044. match = 0;
  3045. if (dwarf_fsect) {
  3046. match = dwarf_fsect;
  3047. for (sinx = 0; sinx < dwarf_nsections; sinx++) {
  3048. if (match->section == index) {
  3049. dwarf_csect = match;
  3050. return;
  3051. }
  3052. match = match->next;
  3053. }
  3054. }
  3055. /* add entry to end of list */
  3056. dwarf_csect = nasm_malloc(sizeof(struct sectlist));
  3057. dwarf_nsections++;
  3058. dwarf_csect->psaa = plinep = saa_init(1L);
  3059. dwarf_csect->line = 1;
  3060. dwarf_csect->offset = 0;
  3061. dwarf_csect->file = 1;
  3062. dwarf_csect->section = index;
  3063. dwarf_csect->next = 0;
  3064. /* set relocatable address at start of line program */
  3065. saa_write8(plinep,DW_LNS_extended_op);
  3066. saa_write8(plinep,is_elf64() ? 9 : 5); /* operand length */
  3067. saa_write8(plinep,DW_LNE_set_address);
  3068. if (is_elf64())
  3069. saa_write64(plinep,0); /* Start Address */
  3070. else
  3071. saa_write32(plinep,0); /* Start Address */
  3072. if (!dwarf_fsect) { /* if first entry */
  3073. dwarf_fsect = dwarf_esect = dwarf_csect;
  3074. dwarf_csect->last = 0;
  3075. } else { /* chain to previous entry */
  3076. dwarf_esect->next = dwarf_csect;
  3077. dwarf_esect = dwarf_csect;
  3078. }
  3079. }
  3080. #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */