utils.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. /*
  2. * Small utility functions for winebuild
  3. *
  4. * Copyright 2000 Alexandre Julliard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #include <assert.h>
  23. #include <ctype.h>
  24. #include <stdarg.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #ifdef HAVE_UNISTD_H
  29. # include <unistd.h>
  30. #endif
  31. #ifdef HAVE_SYS_STAT_H
  32. # include <sys/stat.h>
  33. #endif
  34. #include "wine/list.h"
  35. #include "build.h"
  36. #if defined(_WIN32) && !defined(__CYGWIN__)
  37. # define PATH_SEPARATOR ';'
  38. #else
  39. # define PATH_SEPARATOR ':'
  40. #endif
  41. static struct strarray tmp_files;
  42. static struct strarray empty_strarray;
  43. static const char *output_file_source_name;
  44. static const struct
  45. {
  46. const char *name;
  47. enum target_cpu cpu;
  48. } cpu_names[] =
  49. {
  50. { "i386", CPU_x86 },
  51. { "i486", CPU_x86 },
  52. { "i586", CPU_x86 },
  53. { "i686", CPU_x86 },
  54. { "i786", CPU_x86 },
  55. { "amd64", CPU_x86_64 },
  56. { "x86_64", CPU_x86_64 },
  57. { "powerpc", CPU_POWERPC },
  58. { "arm", CPU_ARM },
  59. { "armv5", CPU_ARM },
  60. { "armv6", CPU_ARM },
  61. { "armv7", CPU_ARM },
  62. { "armv7a", CPU_ARM },
  63. { "arm64", CPU_ARM64 },
  64. { "aarch64", CPU_ARM64 },
  65. };
  66. /* atexit handler to clean tmp files */
  67. void cleanup_tmp_files(void)
  68. {
  69. unsigned int i;
  70. for (i = 0; i < tmp_files.count; i++) if (tmp_files.str[i]) unlink( tmp_files.str[i] );
  71. }
  72. void *xmalloc (size_t size)
  73. {
  74. void *res;
  75. res = malloc (size ? size : 1);
  76. if (res == NULL)
  77. {
  78. fprintf (stderr, "Virtual memory exhausted.\n");
  79. exit (1);
  80. }
  81. return res;
  82. }
  83. void *xrealloc (void *ptr, size_t size)
  84. {
  85. void *res = realloc (ptr, size);
  86. if (size && res == NULL)
  87. {
  88. fprintf (stderr, "Virtual memory exhausted.\n");
  89. exit (1);
  90. }
  91. return res;
  92. }
  93. char *xstrdup( const char *str )
  94. {
  95. char *res = strdup( str );
  96. if (!res)
  97. {
  98. fprintf (stderr, "Virtual memory exhausted.\n");
  99. exit (1);
  100. }
  101. return res;
  102. }
  103. char *strupper(char *s)
  104. {
  105. char *p;
  106. for (p = s; *p; p++) *p = toupper(*p);
  107. return s;
  108. }
  109. int strendswith(const char* str, const char* end)
  110. {
  111. int l = strlen(str);
  112. int m = strlen(end);
  113. return l >= m && strcmp(str + l - m, end) == 0;
  114. }
  115. char *strmake( const char* fmt, ... )
  116. {
  117. int n;
  118. size_t size = 100;
  119. va_list ap;
  120. for (;;)
  121. {
  122. char *p = xmalloc( size );
  123. va_start( ap, fmt );
  124. n = vsnprintf( p, size, fmt, ap );
  125. va_end( ap );
  126. if (n == -1) size *= 2;
  127. else if ((size_t)n >= size) size = n + 1;
  128. else return p;
  129. free( p );
  130. }
  131. }
  132. static struct strarray strarray_copy( struct strarray src )
  133. {
  134. struct strarray array;
  135. array.count = src.count;
  136. array.max = src.max;
  137. array.str = xmalloc( array.max * sizeof(*array.str) );
  138. memcpy( array.str, src.str, array.count * sizeof(*array.str) );
  139. return array;
  140. }
  141. static void strarray_add_one( struct strarray *array, const char *str )
  142. {
  143. if (array->count == array->max)
  144. {
  145. array->max *= 2;
  146. if (array->max < 16) array->max = 16;
  147. array->str = xrealloc( array->str, array->max * sizeof(*array->str) );
  148. }
  149. array->str[array->count++] = str;
  150. }
  151. void strarray_add( struct strarray *array, ... )
  152. {
  153. va_list valist;
  154. const char *str;
  155. va_start( valist, array );
  156. while ((str = va_arg( valist, const char *))) strarray_add_one( array, str );
  157. va_end( valist );
  158. }
  159. void strarray_addv( struct strarray *array, char * const *argv )
  160. {
  161. while (*argv) strarray_add_one( array, *argv++ );
  162. }
  163. void strarray_addall( struct strarray *array, struct strarray args )
  164. {
  165. unsigned int i;
  166. for (i = 0; i < args.count; i++) strarray_add_one( array, args.str[i] );
  167. }
  168. struct strarray strarray_fromstring( const char *str, const char *delim )
  169. {
  170. const char *tok;
  171. struct strarray array = empty_strarray;
  172. char *buf = xstrdup( str );
  173. for (tok = strtok( buf, delim ); tok; tok = strtok( NULL, delim ))
  174. strarray_add_one( &array, strdup( tok ));
  175. free( buf );
  176. return array;
  177. }
  178. void fatal_error( const char *msg, ... )
  179. {
  180. va_list valist;
  181. va_start( valist, msg );
  182. if (input_file_name)
  183. {
  184. fprintf( stderr, "%s:", input_file_name );
  185. if (current_line)
  186. fprintf( stderr, "%d:", current_line );
  187. fputc( ' ', stderr );
  188. }
  189. else fprintf( stderr, "winebuild: " );
  190. vfprintf( stderr, msg, valist );
  191. va_end( valist );
  192. exit(1);
  193. }
  194. void fatal_perror( const char *msg, ... )
  195. {
  196. va_list valist;
  197. va_start( valist, msg );
  198. if (input_file_name)
  199. {
  200. fprintf( stderr, "%s:", input_file_name );
  201. if (current_line)
  202. fprintf( stderr, "%d:", current_line );
  203. fputc( ' ', stderr );
  204. }
  205. vfprintf( stderr, msg, valist );
  206. perror( " " );
  207. va_end( valist );
  208. exit(1);
  209. }
  210. void error( const char *msg, ... )
  211. {
  212. va_list valist;
  213. va_start( valist, msg );
  214. if (input_file_name)
  215. {
  216. fprintf( stderr, "%s:", input_file_name );
  217. if (current_line)
  218. fprintf( stderr, "%d:", current_line );
  219. fputc( ' ', stderr );
  220. }
  221. vfprintf( stderr, msg, valist );
  222. va_end( valist );
  223. nb_errors++;
  224. }
  225. void warning( const char *msg, ... )
  226. {
  227. va_list valist;
  228. if (!display_warnings) return;
  229. va_start( valist, msg );
  230. if (input_file_name)
  231. {
  232. fprintf( stderr, "%s:", input_file_name );
  233. if (current_line)
  234. fprintf( stderr, "%d:", current_line );
  235. fputc( ' ', stderr );
  236. }
  237. fprintf( stderr, "warning: " );
  238. vfprintf( stderr, msg, valist );
  239. va_end( valist );
  240. }
  241. int output( const char *format, ... )
  242. {
  243. int ret;
  244. va_list valist;
  245. va_start( valist, format );
  246. ret = vfprintf( output_file, format, valist );
  247. va_end( valist );
  248. if (ret < 0) fatal_perror( "Output error" );
  249. return ret;
  250. }
  251. static struct strarray get_tools_path(void)
  252. {
  253. static int done;
  254. static struct strarray dirs;
  255. if (!done)
  256. {
  257. dirs = strarray_copy( tools_path );
  258. /* then append the PATH directories */
  259. if (getenv( "PATH" ))
  260. {
  261. char *p = xstrdup( getenv( "PATH" ));
  262. while (*p)
  263. {
  264. strarray_add_one( &dirs, p );
  265. while (*p && *p != PATH_SEPARATOR) p++;
  266. if (!*p) break;
  267. *p++ = 0;
  268. }
  269. }
  270. done = 1;
  271. }
  272. return dirs;
  273. }
  274. /* find a binary in the path */
  275. static const char *find_binary( const char *prefix, const char *name )
  276. {
  277. struct strarray dirs = get_tools_path();
  278. unsigned int i, maxlen = 0;
  279. struct stat st;
  280. char *p, *file;
  281. if (strchr( name, '/' )) return name;
  282. if (!prefix) prefix = "";
  283. for (i = 0; i < dirs.count; i++) maxlen = max( maxlen, strlen(dirs.str[i]) + 2 );
  284. file = xmalloc( maxlen + strlen(prefix) + strlen(name) + sizeof(EXEEXT) + 1 );
  285. for (i = 0; i < dirs.count; i++)
  286. {
  287. strcpy( file, dirs.str[i] );
  288. p = file + strlen(file);
  289. if (p == file) *p++ = '.';
  290. if (p[-1] != '/') *p++ = '/';
  291. if (*prefix)
  292. {
  293. strcpy( p, prefix );
  294. p += strlen(p);
  295. *p++ = '-';
  296. }
  297. strcpy( p, name );
  298. strcat( p, EXEEXT );
  299. if (!stat( file, &st ) && S_ISREG(st.st_mode) && (st.st_mode & 0111)) return file;
  300. }
  301. free( file );
  302. return NULL;
  303. }
  304. void spawn( struct strarray args )
  305. {
  306. unsigned int i;
  307. int status;
  308. const char *argv0 = find_binary( NULL, args.str[0] );
  309. if (argv0) args.str[0] = argv0;
  310. strarray_add_one( &args, NULL );
  311. if (verbose)
  312. for (i = 0; args.str[i]; i++)
  313. fprintf( stderr, "%s%c", args.str[i], args.str[i+1] ? ' ' : '\n' );
  314. if ((status = _spawnvp( _P_WAIT, args.str[0], args.str )))
  315. {
  316. if (status > 0) fatal_error( "%s failed with status %u\n", args.str[0], status );
  317. else fatal_perror( "winebuild" );
  318. exit( 1 );
  319. }
  320. }
  321. /* find a build tool in the path, trying the various names */
  322. struct strarray find_tool( const char *name, const char * const *names )
  323. {
  324. const char *file;
  325. const char *alt_names[2];
  326. if (!names)
  327. {
  328. alt_names[0] = name;
  329. alt_names[1] = NULL;
  330. names = alt_names;
  331. }
  332. while (*names)
  333. {
  334. if ((file = find_binary( target_alias, *names ))
  335. || (names == alt_names && (file = find_binary( "llvm", *names ))))
  336. {
  337. struct strarray ret = empty_strarray;
  338. strarray_add_one( &ret, file );
  339. return ret;
  340. }
  341. names++;
  342. }
  343. fatal_error( "cannot find the '%s' tool\n", name );
  344. }
  345. struct strarray get_as_command(void)
  346. {
  347. struct strarray args;
  348. unsigned int i;
  349. if (cc_command.count)
  350. {
  351. args = strarray_copy( cc_command );
  352. strarray_add( &args, "-xassembler", "-c", NULL );
  353. if (force_pointer_size)
  354. strarray_add_one( &args, (force_pointer_size == 8) ? "-m64" : "-m32" );
  355. if (cpu_option) strarray_add_one( &args, strmake("-mcpu=%s", cpu_option) );
  356. if (fpu_option) strarray_add_one( &args, strmake("-mfpu=%s", fpu_option) );
  357. if (arch_option) strarray_add_one( &args, strmake("-march=%s", arch_option) );
  358. for (i = 0; i < tools_path.count; i++)
  359. strarray_add_one( &args, strmake("-B%s", tools_path.str[i] ));
  360. return args;
  361. }
  362. if (!as_command.count)
  363. {
  364. static const char * const commands[] = { "gas", "as", NULL };
  365. as_command = find_tool( "as", commands );
  366. }
  367. args = strarray_copy( as_command );
  368. if (force_pointer_size)
  369. {
  370. switch (target_platform)
  371. {
  372. case PLATFORM_APPLE:
  373. strarray_add( &args, "-arch", (force_pointer_size == 8) ? "x86_64" : "i386", NULL );
  374. break;
  375. default:
  376. switch(target_cpu)
  377. {
  378. case CPU_POWERPC:
  379. strarray_add_one( &args, (force_pointer_size == 8) ? "-a64" : "-a32" );
  380. break;
  381. default:
  382. strarray_add_one( &args, (force_pointer_size == 8) ? "--64" : "--32" );
  383. break;
  384. }
  385. break;
  386. }
  387. }
  388. if (cpu_option) strarray_add_one( &args, strmake("-mcpu=%s", cpu_option) );
  389. if (fpu_option) strarray_add_one( &args, strmake("-mfpu=%s", fpu_option) );
  390. return args;
  391. }
  392. struct strarray get_ld_command(void)
  393. {
  394. struct strarray args;
  395. if (!ld_command.count)
  396. {
  397. static const char * const commands[] = { "ld", "gld", NULL };
  398. ld_command = find_tool( "ld", commands );
  399. }
  400. args = strarray_copy( ld_command );
  401. if (force_pointer_size)
  402. {
  403. switch (target_platform)
  404. {
  405. case PLATFORM_APPLE:
  406. strarray_add( &args, "-arch", (force_pointer_size == 8) ? "x86_64" : "i386", NULL );
  407. break;
  408. case PLATFORM_FREEBSD:
  409. strarray_add( &args, "-m", (force_pointer_size == 8) ? "elf_x86_64_fbsd" : "elf_i386_fbsd", NULL );
  410. break;
  411. case PLATFORM_WINDOWS:
  412. strarray_add( &args, "-m", (force_pointer_size == 8) ? "i386pep" : "i386pe", NULL );
  413. break;
  414. default:
  415. switch(target_cpu)
  416. {
  417. case CPU_POWERPC:
  418. strarray_add( &args, "-m", (force_pointer_size == 8) ? "elf64ppc" : "elf32ppc", NULL );
  419. break;
  420. default:
  421. strarray_add( &args, "-m", (force_pointer_size == 8) ? "elf_x86_64" : "elf_i386", NULL );
  422. break;
  423. }
  424. break;
  425. }
  426. }
  427. if (target_cpu == CPU_ARM && target_platform != PLATFORM_WINDOWS)
  428. strarray_add( &args, "--no-wchar-size-warning", NULL );
  429. return args;
  430. }
  431. const char *get_nm_command(void)
  432. {
  433. if (!nm_command.count)
  434. {
  435. static const char * const commands[] = { "nm", "gnm", NULL };
  436. nm_command = find_tool( "nm", commands );
  437. }
  438. if (nm_command.count > 1)
  439. fatal_error( "multiple arguments in nm command not supported yet\n" );
  440. return nm_command.str[0];
  441. }
  442. /* get a name for a temp file, automatically cleaned up on exit */
  443. char *get_temp_file_name( const char *prefix, const char *suffix )
  444. {
  445. char *name;
  446. const char *ext, *basename;
  447. int fd;
  448. if (!prefix || !prefix[0]) prefix = "winebuild";
  449. if (!suffix) suffix = "";
  450. if ((basename = strrchr( prefix, '/' ))) basename++;
  451. else basename = prefix;
  452. if (!(ext = strchr( basename, '.' ))) ext = prefix + strlen(prefix);
  453. name = xmalloc( sizeof("/tmp/") + (ext - prefix) + sizeof(".XXXXXX") + strlen(suffix) );
  454. memcpy( name, prefix, ext - prefix );
  455. strcpy( name + (ext - prefix), ".XXXXXX" );
  456. strcat( name, suffix );
  457. if ((fd = mkstemps( name, strlen(suffix) )) == -1)
  458. {
  459. strcpy( name, "/tmp/" );
  460. memcpy( name + 5, basename, ext - basename );
  461. strcpy( name + 5 + (ext - basename), ".XXXXXX" );
  462. strcat( name, suffix );
  463. if ((fd = mkstemps( name, strlen(suffix) )) == -1)
  464. fatal_error( "could not generate a temp file\n" );
  465. }
  466. close( fd );
  467. strarray_add_one( &tmp_files, name );
  468. return name;
  469. }
  470. /*******************************************************************
  471. * buffer management
  472. *
  473. * Function for reading from/writing to a memory buffer.
  474. */
  475. int byte_swapped = 0;
  476. const char *input_buffer_filename;
  477. const unsigned char *input_buffer;
  478. size_t input_buffer_pos;
  479. size_t input_buffer_size;
  480. unsigned char *output_buffer;
  481. size_t output_buffer_pos;
  482. size_t output_buffer_rva;
  483. size_t output_buffer_size;
  484. struct label
  485. {
  486. struct list entry;
  487. char *name;
  488. size_t pos;
  489. size_t rva;
  490. };
  491. static struct list labels = LIST_INIT( labels );
  492. struct label *get_label( const char *name )
  493. {
  494. struct label *label;
  495. LIST_FOR_EACH_ENTRY( label, &labels, struct label, entry )
  496. {
  497. if (!strcmp(name, label->name))
  498. return label;
  499. }
  500. label = xmalloc( sizeof(*label) );
  501. label->name = xstrdup( name );
  502. label->pos = 0;
  503. label->rva = 0;
  504. list_add_tail( &labels, &label->entry );
  505. return label;
  506. }
  507. size_t label_pos( const char *name )
  508. {
  509. struct label *label = get_label( name );
  510. return label->pos;
  511. }
  512. size_t label_rva( const char *name )
  513. {
  514. struct label *label = get_label( name );
  515. return label->rva;
  516. }
  517. size_t label_rva_align( const char *name )
  518. {
  519. const unsigned int page_size = get_page_size();
  520. size_t rva = label_rva( name );
  521. size_t size = page_size - (rva % page_size);
  522. if (size != page_size) rva += size;
  523. return rva;
  524. }
  525. void put_label( const char *name )
  526. {
  527. struct label *label = get_label( name );
  528. if (label->pos || label->rva)
  529. {
  530. assert( label->pos == output_buffer_pos );
  531. assert( label->rva == output_buffer_rva );
  532. }
  533. label->pos = output_buffer_pos;
  534. label->rva = output_buffer_rva;
  535. }
  536. void free_labels( void )
  537. {
  538. struct label *label, *label2;
  539. LIST_FOR_EACH_ENTRY_SAFE( label, label2, &labels, struct label, entry )
  540. {
  541. list_remove( &label->entry );
  542. free( label->name );
  543. free( label );
  544. }
  545. }
  546. static void check_output_buffer_space( size_t size )
  547. {
  548. if (output_buffer_pos + size >= output_buffer_size)
  549. {
  550. output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
  551. output_buffer = xrealloc( output_buffer, output_buffer_size );
  552. }
  553. }
  554. void init_input_buffer( const char *file )
  555. {
  556. int fd;
  557. struct stat st;
  558. unsigned char *buffer;
  559. if ((fd = open( file, O_RDONLY | O_BINARY )) == -1) fatal_perror( "Cannot open %s", file );
  560. if ((fstat( fd, &st ) == -1)) fatal_perror( "Cannot stat %s", file );
  561. if (!st.st_size) fatal_error( "%s is an empty file\n", file );
  562. input_buffer = buffer = xmalloc( st.st_size );
  563. if (read( fd, buffer, st.st_size ) != st.st_size) fatal_error( "Cannot read %s\n", file );
  564. close( fd );
  565. input_buffer_filename = xstrdup( file );
  566. input_buffer_size = st.st_size;
  567. input_buffer_pos = 0;
  568. byte_swapped = 0;
  569. }
  570. void init_output_buffer(void)
  571. {
  572. output_buffer_size = 1024;
  573. output_buffer_pos = 0;
  574. output_buffer_rva = 0;
  575. output_buffer = xmalloc( output_buffer_size );
  576. free_labels();
  577. }
  578. void flush_output_buffer(void)
  579. {
  580. open_output_file();
  581. if (fwrite( output_buffer, 1, output_buffer_pos, output_file ) != output_buffer_pos)
  582. fatal_error( "Error writing to %s\n", output_file_name );
  583. close_output_file();
  584. free( output_buffer );
  585. free_labels();
  586. }
  587. unsigned char get_byte(void)
  588. {
  589. if (input_buffer_pos >= input_buffer_size)
  590. fatal_error( "%s is a truncated file\n", input_buffer_filename );
  591. return input_buffer[input_buffer_pos++];
  592. }
  593. unsigned short get_word(void)
  594. {
  595. unsigned short ret;
  596. if (input_buffer_pos + sizeof(ret) > input_buffer_size)
  597. fatal_error( "%s is a truncated file\n", input_buffer_filename );
  598. memcpy( &ret, input_buffer + input_buffer_pos, sizeof(ret) );
  599. if (byte_swapped) ret = (ret << 8) | (ret >> 8);
  600. input_buffer_pos += sizeof(ret);
  601. return ret;
  602. }
  603. unsigned int get_dword(void)
  604. {
  605. unsigned int ret;
  606. if (input_buffer_pos + sizeof(ret) > input_buffer_size)
  607. fatal_error( "%s is a truncated file\n", input_buffer_filename );
  608. memcpy( &ret, input_buffer + input_buffer_pos, sizeof(ret) );
  609. if (byte_swapped)
  610. ret = ((ret << 24) | ((ret << 8) & 0x00ff0000) | ((ret >> 8) & 0x0000ff00) | (ret >> 24));
  611. input_buffer_pos += sizeof(ret);
  612. return ret;
  613. }
  614. void put_data( const void *data, size_t size )
  615. {
  616. check_output_buffer_space( size );
  617. memcpy( output_buffer + output_buffer_pos, data, size );
  618. output_buffer_pos += size;
  619. output_buffer_rva += size;
  620. }
  621. void put_byte( unsigned char val )
  622. {
  623. check_output_buffer_space( 1 );
  624. output_buffer[output_buffer_pos++] = val;
  625. output_buffer_rva++;
  626. }
  627. void put_word( unsigned short val )
  628. {
  629. if (byte_swapped) val = (val << 8) | (val >> 8);
  630. put_data( &val, sizeof(val) );
  631. }
  632. void put_dword( unsigned int val )
  633. {
  634. if (byte_swapped)
  635. val = ((val << 24) | ((val << 8) & 0x00ff0000) | ((val >> 8) & 0x0000ff00) | (val >> 24));
  636. put_data( &val, sizeof(val) );
  637. }
  638. void put_qword( unsigned int val )
  639. {
  640. if (byte_swapped)
  641. {
  642. put_dword( 0 );
  643. put_dword( val );
  644. }
  645. else
  646. {
  647. put_dword( val );
  648. put_dword( 0 );
  649. }
  650. }
  651. /* pointer-sized word */
  652. void put_pword( unsigned int val )
  653. {
  654. if (get_ptr_size() == 8) put_qword( val );
  655. else put_dword( val );
  656. }
  657. void put_str( const char *str )
  658. {
  659. put_data( str, strlen(str) + 1 );
  660. }
  661. void align_output( unsigned int align )
  662. {
  663. size_t size = align - (output_buffer_pos % align);
  664. if (size == align) return;
  665. check_output_buffer_space( size );
  666. memset( output_buffer + output_buffer_pos, 0, size );
  667. output_buffer_pos += size;
  668. }
  669. void align_output_rva( unsigned int file_align, unsigned int rva_align )
  670. {
  671. size_t size = rva_align - (output_buffer_rva % rva_align);
  672. if (size != rva_align) output_buffer_rva += size;
  673. align_output( file_align );
  674. }
  675. /* output a standard header for generated files */
  676. void output_standard_file_header(void)
  677. {
  678. if (spec_file_name)
  679. output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name );
  680. else
  681. output( "/* File generated automatically; do not edit! */\n" );
  682. output( "/* This file can be copied, modified and distributed without restriction. */\n\n" );
  683. }
  684. /* dump a byte stream into the assembly code */
  685. void dump_bytes( const void *buffer, unsigned int size )
  686. {
  687. unsigned int i;
  688. const unsigned char *ptr = buffer;
  689. if (!size) return;
  690. output( "\t.byte " );
  691. for (i = 0; i < size - 1; i++, ptr++)
  692. {
  693. if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr );
  694. else output( "0x%02x,", *ptr );
  695. }
  696. output( "0x%02x\n", *ptr );
  697. }
  698. /*******************************************************************
  699. * open_input_file
  700. *
  701. * Open a file in the given srcdir and set the input_file_name global variable.
  702. */
  703. FILE *open_input_file( const char *srcdir, const char *name )
  704. {
  705. char *fullname;
  706. FILE *file = fopen( name, "r" );
  707. if (!file && srcdir)
  708. {
  709. fullname = strmake( "%s/%s", srcdir, name );
  710. file = fopen( fullname, "r" );
  711. }
  712. else fullname = xstrdup( name );
  713. if (!file) fatal_error( "Cannot open file '%s'\n", fullname );
  714. input_file_name = fullname;
  715. current_line = 1;
  716. return file;
  717. }
  718. /*******************************************************************
  719. * close_input_file
  720. *
  721. * Close the current input file (must have been opened with open_input_file).
  722. */
  723. void close_input_file( FILE *file )
  724. {
  725. fclose( file );
  726. free( input_file_name );
  727. input_file_name = NULL;
  728. current_line = 0;
  729. }
  730. /*******************************************************************
  731. * open_output_file
  732. */
  733. void open_output_file(void)
  734. {
  735. if (output_file_name)
  736. {
  737. if (strendswith( output_file_name, ".o" ))
  738. output_file_source_name = open_temp_output_file( ".s" );
  739. else
  740. if (!(output_file = fopen( output_file_name, "w" )))
  741. fatal_error( "Unable to create output file '%s'\n", output_file_name );
  742. }
  743. else output_file = stdout;
  744. }
  745. /*******************************************************************
  746. * close_output_file
  747. */
  748. void close_output_file(void)
  749. {
  750. if (!output_file || !output_file_name) return;
  751. if (fclose( output_file ) < 0) fatal_perror( "fclose" );
  752. if (output_file_source_name) assemble_file( output_file_source_name, output_file_name );
  753. output_file = NULL;
  754. }
  755. /*******************************************************************
  756. * open_temp_output_file
  757. */
  758. char *open_temp_output_file( const char *suffix )
  759. {
  760. char *tmp_file = get_temp_file_name( output_file_name, suffix );
  761. if (!(output_file = fopen( tmp_file, "w" )))
  762. fatal_error( "Unable to create output file '%s'\n", tmp_file );
  763. return tmp_file;
  764. }
  765. /*******************************************************************
  766. * remove_stdcall_decoration
  767. *
  768. * Remove a possible @xx suffix from a function name.
  769. * Return the numerical value of the suffix, or -1 if none.
  770. */
  771. int remove_stdcall_decoration( char *name )
  772. {
  773. char *p, *end = strrchr( name, '@' );
  774. if (!end || !end[1] || end == name) return -1;
  775. if (target_cpu != CPU_x86) return -1;
  776. /* make sure all the rest is digits */
  777. for (p = end + 1; *p; p++) if (!isdigit(*p)) return -1;
  778. *end = 0;
  779. return atoi( end + 1 );
  780. }
  781. /*******************************************************************
  782. * assemble_file
  783. *
  784. * Run a file through the assembler.
  785. */
  786. void assemble_file( const char *src_file, const char *obj_file )
  787. {
  788. struct strarray args = get_as_command();
  789. strarray_add( &args, "-o", obj_file, src_file, NULL );
  790. spawn( args );
  791. }
  792. /*******************************************************************
  793. * alloc_dll_spec
  794. *
  795. * Create a new dll spec file descriptor
  796. */
  797. DLLSPEC *alloc_dll_spec(void)
  798. {
  799. DLLSPEC *spec;
  800. spec = xmalloc( sizeof(*spec) );
  801. memset( spec, 0, sizeof(*spec) );
  802. spec->type = SPEC_WIN32;
  803. spec->base = MAX_ORDINALS;
  804. spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
  805. spec->subsystem = 0;
  806. spec->subsystem_major = 4;
  807. spec->subsystem_minor = 0;
  808. if (get_ptr_size() > 4)
  809. spec->characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
  810. else
  811. spec->characteristics |= IMAGE_FILE_32BIT_MACHINE;
  812. spec->dll_characteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
  813. return spec;
  814. }
  815. /*******************************************************************
  816. * free_dll_spec
  817. *
  818. * Free dll spec file descriptor
  819. */
  820. void free_dll_spec( DLLSPEC *spec )
  821. {
  822. int i;
  823. for (i = 0; i < spec->nb_entry_points; i++)
  824. {
  825. ORDDEF *odp = &spec->entry_points[i];
  826. free( odp->name );
  827. free( odp->export_name );
  828. free( odp->link_name );
  829. free( odp->impl_name );
  830. }
  831. free( spec->file_name );
  832. free( spec->dll_name );
  833. free( spec->c_name );
  834. free( spec->init_func );
  835. free( spec->entry_points );
  836. free( spec->names );
  837. free( spec->ordinals );
  838. free( spec->resources );
  839. free( spec->syscalls );
  840. free( spec );
  841. }
  842. /*******************************************************************
  843. * make_c_identifier
  844. *
  845. * Map a string to a valid C identifier.
  846. */
  847. char *make_c_identifier( const char *str )
  848. {
  849. char *p, buffer[256];
  850. for (p = buffer; *str && p < buffer+sizeof(buffer)-1; p++, str++)
  851. {
  852. if (isalnum(*str)) *p = *str;
  853. else *p = '_';
  854. }
  855. *p = 0;
  856. return xstrdup( buffer );
  857. }
  858. /*******************************************************************
  859. * get_stub_name
  860. *
  861. * Generate an internal name for a stub entry point.
  862. */
  863. const char *get_stub_name( const ORDDEF *odp, const DLLSPEC *spec )
  864. {
  865. static char *buffer;
  866. free( buffer );
  867. if (odp->name || odp->export_name)
  868. {
  869. char *p;
  870. buffer = strmake( "__wine_stub_%s", odp->name ? odp->name : odp->export_name );
  871. /* make sure name is a legal C identifier */
  872. for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
  873. if (!*p) return buffer;
  874. free( buffer );
  875. }
  876. buffer = strmake( "__wine_stub_%s_%d", make_c_identifier(spec->file_name), odp->ordinal );
  877. return buffer;
  878. }
  879. /* return the stdcall-decorated name for an entry point */
  880. const char *get_link_name( const ORDDEF *odp )
  881. {
  882. static char *buffer;
  883. char *ret;
  884. if (target_cpu != CPU_x86) return odp->link_name;
  885. switch (odp->type)
  886. {
  887. case TYPE_STDCALL:
  888. if (target_platform == PLATFORM_WINDOWS)
  889. {
  890. if (odp->flags & FLAG_THISCALL) return odp->link_name;
  891. if (odp->flags & FLAG_FASTCALL) ret = strmake( "@%s@%u", odp->link_name, get_args_size( odp ));
  892. else if (!kill_at) ret = strmake( "%s@%u", odp->link_name, get_args_size( odp ));
  893. else return odp->link_name;
  894. }
  895. else
  896. {
  897. if (odp->flags & FLAG_THISCALL) ret = strmake( "__thiscall_%s", odp->link_name );
  898. else if (odp->flags & FLAG_FASTCALL) ret = strmake( "__fastcall_%s", odp->link_name );
  899. else return odp->link_name;
  900. }
  901. break;
  902. case TYPE_PASCAL:
  903. if (target_platform == PLATFORM_WINDOWS && !kill_at)
  904. {
  905. int args = get_args_size( odp );
  906. if (odp->flags & FLAG_REGISTER) args += get_ptr_size(); /* context argument */
  907. ret = strmake( "%s@%u", odp->link_name, args );
  908. }
  909. else return odp->link_name;
  910. break;
  911. default:
  912. return odp->link_name;
  913. }
  914. free( buffer );
  915. buffer = ret;
  916. return ret;
  917. }
  918. /* parse a cpu name and return the corresponding value */
  919. int get_cpu_from_name( const char *name )
  920. {
  921. unsigned int i;
  922. for (i = 0; i < ARRAY_SIZE(cpu_names); i++)
  923. if (!strcmp( cpu_names[i].name, name )) return cpu_names[i].cpu;
  924. return -1;
  925. }
  926. /*****************************************************************
  927. * Function: get_alignment
  928. *
  929. * Description:
  930. * According to the info page for gas, the .align directive behaves
  931. * differently on different systems. On some architectures, the
  932. * argument of a .align directive is the number of bytes to pad to, so
  933. * to align on an 8-byte boundary you'd say
  934. * .align 8
  935. * On other systems, the argument is "the number of low-order zero bits
  936. * that the location counter must have after advancement." So to
  937. * align on an 8-byte boundary you'd say
  938. * .align 3
  939. *
  940. * The reason gas is written this way is that it's trying to mimic
  941. * native assemblers for the various architectures it runs on. gas
  942. * provides other directives that work consistently across
  943. * architectures, but of course we want to work on all arches with or
  944. * without gas. Hence this function.
  945. *
  946. *
  947. * Parameters:
  948. * align -- the number of bytes to align to. Must be a power of 2.
  949. */
  950. unsigned int get_alignment(unsigned int align)
  951. {
  952. unsigned int n;
  953. assert( !(align & (align - 1)) );
  954. switch(target_cpu)
  955. {
  956. case CPU_x86:
  957. case CPU_x86_64:
  958. if (target_platform != PLATFORM_APPLE) return align;
  959. /* fall through */
  960. case CPU_POWERPC:
  961. case CPU_ARM:
  962. case CPU_ARM64:
  963. n = 0;
  964. while ((1u << n) != align) n++;
  965. return n;
  966. }
  967. /* unreached */
  968. assert(0);
  969. return 0;
  970. }
  971. /* return the page size for the target CPU */
  972. unsigned int get_page_size(void)
  973. {
  974. switch(target_cpu)
  975. {
  976. case CPU_x86:
  977. case CPU_x86_64:
  978. case CPU_POWERPC:
  979. case CPU_ARM:
  980. return 0x1000;
  981. case CPU_ARM64:
  982. return 0x10000;
  983. }
  984. /* unreached */
  985. assert(0);
  986. return 0;
  987. }
  988. /* return the size of a pointer on the target CPU */
  989. unsigned int get_ptr_size(void)
  990. {
  991. switch(target_cpu)
  992. {
  993. case CPU_x86:
  994. case CPU_POWERPC:
  995. case CPU_ARM:
  996. return 4;
  997. case CPU_x86_64:
  998. case CPU_ARM64:
  999. return 8;
  1000. }
  1001. /* unreached */
  1002. assert(0);
  1003. return 0;
  1004. }
  1005. /* return the total size in bytes of the arguments on the stack */
  1006. unsigned int get_args_size( const ORDDEF *odp )
  1007. {
  1008. int i, size;
  1009. for (i = size = 0; i < odp->u.func.nb_args; i++)
  1010. {
  1011. switch (odp->u.func.args[i])
  1012. {
  1013. case ARG_INT64:
  1014. case ARG_DOUBLE:
  1015. size += 8;
  1016. break;
  1017. case ARG_INT128:
  1018. /* int128 is passed as pointer on x86_64 */
  1019. if (target_cpu != CPU_x86_64)
  1020. {
  1021. size += 16;
  1022. break;
  1023. }
  1024. /* fall through */
  1025. default:
  1026. size += get_ptr_size();
  1027. break;
  1028. }
  1029. }
  1030. return size;
  1031. }
  1032. /* return the assembly name for a C symbol */
  1033. const char *asm_name( const char *sym )
  1034. {
  1035. static char *buffer;
  1036. switch (target_platform)
  1037. {
  1038. case PLATFORM_WINDOWS:
  1039. if (target_cpu != CPU_x86) return sym;
  1040. if (sym[0] == '@') return sym; /* fastcall */
  1041. /* fall through */
  1042. case PLATFORM_APPLE:
  1043. if (sym[0] == '.' && sym[1] == 'L') return sym;
  1044. free( buffer );
  1045. buffer = strmake( "_%s", sym );
  1046. return buffer;
  1047. default:
  1048. return sym;
  1049. }
  1050. }
  1051. /* return an assembly function declaration for a C function name */
  1052. const char *func_declaration( const char *func )
  1053. {
  1054. static char *buffer;
  1055. switch (target_platform)
  1056. {
  1057. case PLATFORM_APPLE:
  1058. return "";
  1059. case PLATFORM_WINDOWS:
  1060. free( buffer );
  1061. buffer = strmake( ".def %s; .scl 2; .type 32; .endef", asm_name(func) );
  1062. break;
  1063. default:
  1064. free( buffer );
  1065. switch(target_cpu)
  1066. {
  1067. case CPU_ARM:
  1068. case CPU_ARM64:
  1069. buffer = strmake( ".type %s,%%function", func );
  1070. break;
  1071. default:
  1072. buffer = strmake( ".type %s,@function", func );
  1073. break;
  1074. }
  1075. break;
  1076. }
  1077. return buffer;
  1078. }
  1079. /* output a size declaration for an assembly function */
  1080. void output_function_size( const char *name )
  1081. {
  1082. switch (target_platform)
  1083. {
  1084. case PLATFORM_APPLE:
  1085. case PLATFORM_WINDOWS:
  1086. break;
  1087. default:
  1088. output( "\t.size %s, .-%s\n", name, name );
  1089. break;
  1090. }
  1091. }
  1092. /* output a .cfi directive */
  1093. void output_cfi( const char *format, ... )
  1094. {
  1095. va_list valist;
  1096. if (!unwind_tables) return;
  1097. va_start( valist, format );
  1098. fputc( '\t', output_file );
  1099. vfprintf( output_file, format, valist );
  1100. fputc( '\n', output_file );
  1101. va_end( valist );
  1102. }
  1103. /* output an RVA pointer */
  1104. void output_rva( const char *format, ... )
  1105. {
  1106. va_list valist;
  1107. va_start( valist, format );
  1108. switch (target_platform)
  1109. {
  1110. case PLATFORM_WINDOWS:
  1111. output( "\t.rva " );
  1112. vfprintf( output_file, format, valist );
  1113. fputc( '\n', output_file );
  1114. break;
  1115. default:
  1116. output( "\t.long " );
  1117. vfprintf( output_file, format, valist );
  1118. output( " - .L__wine_spec_rva_base\n" );
  1119. break;
  1120. }
  1121. va_end( valist );
  1122. }
  1123. /* output the GNU note for non-exec stack */
  1124. void output_gnu_stack_note(void)
  1125. {
  1126. switch (target_platform)
  1127. {
  1128. case PLATFORM_WINDOWS:
  1129. case PLATFORM_APPLE:
  1130. break;
  1131. default:
  1132. switch(target_cpu)
  1133. {
  1134. case CPU_ARM:
  1135. case CPU_ARM64:
  1136. output( "\t.section .note.GNU-stack,\"\",%%progbits\n" );
  1137. break;
  1138. default:
  1139. output( "\t.section .note.GNU-stack,\"\",@progbits\n" );
  1140. break;
  1141. }
  1142. break;
  1143. }
  1144. }
  1145. /* return a global symbol declaration for an assembly symbol */
  1146. const char *asm_globl( const char *func )
  1147. {
  1148. static char *buffer;
  1149. free( buffer );
  1150. switch (target_platform)
  1151. {
  1152. case PLATFORM_APPLE:
  1153. buffer = strmake( "\t.globl _%s\n\t.private_extern _%s\n_%s:", func, func, func );
  1154. break;
  1155. case PLATFORM_WINDOWS:
  1156. buffer = strmake( "\t.globl %s%s\n%s%s:", target_cpu == CPU_x86 ? "_" : "", func,
  1157. target_cpu == CPU_x86 ? "_" : "", func );
  1158. break;
  1159. default:
  1160. buffer = strmake( "\t.globl %s\n\t.hidden %s\n%s:", func, func, func );
  1161. break;
  1162. }
  1163. return buffer;
  1164. }
  1165. const char *get_asm_ptr_keyword(void)
  1166. {
  1167. switch(get_ptr_size())
  1168. {
  1169. case 4: return ".long";
  1170. case 8: return ".quad";
  1171. }
  1172. assert(0);
  1173. return NULL;
  1174. }
  1175. const char *get_asm_string_keyword(void)
  1176. {
  1177. switch (target_platform)
  1178. {
  1179. case PLATFORM_APPLE:
  1180. return ".asciz";
  1181. default:
  1182. return ".string";
  1183. }
  1184. }
  1185. const char *get_asm_export_section(void)
  1186. {
  1187. switch (target_platform)
  1188. {
  1189. case PLATFORM_APPLE: return ".data";
  1190. case PLATFORM_WINDOWS: return ".section .edata";
  1191. default: return ".section .data";
  1192. }
  1193. }
  1194. const char *get_asm_rodata_section(void)
  1195. {
  1196. switch (target_platform)
  1197. {
  1198. case PLATFORM_APPLE: return ".const";
  1199. default: return ".section .rodata";
  1200. }
  1201. }
  1202. const char *get_asm_rsrc_section(void)
  1203. {
  1204. switch (target_platform)
  1205. {
  1206. case PLATFORM_APPLE: return ".data";
  1207. case PLATFORM_WINDOWS: return ".section .rsrc";
  1208. default: return ".section .data";
  1209. }
  1210. }
  1211. const char *get_asm_string_section(void)
  1212. {
  1213. switch (target_platform)
  1214. {
  1215. case PLATFORM_APPLE: return ".cstring";
  1216. default: return ".section .rodata";
  1217. }
  1218. }
  1219. /*******************************************************************
  1220. * sort_func_list
  1221. *
  1222. * Sort a list of functions, removing duplicates.
  1223. */
  1224. int sort_func_list( ORDDEF **list, int count, int (*compare)(const void *, const void *) )
  1225. {
  1226. int i, j;
  1227. if (!count) return 0;
  1228. qsort( list, count, sizeof(*list), compare );
  1229. for (i = j = 0; i < count; i++)
  1230. {
  1231. if (compare( &list[j], &list[i] )) list[++j] = list[i];
  1232. }
  1233. return j + 1;
  1234. }