don't check when its clang masquerading as gcc
[AROS.git] / tools / collect-aros / gensets.c
blobcd66ac3608385dce6402274262822c1c80afed87
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <ctype.h>
10 #include <errno.h>
12 #include "misc.h"
14 typedef struct setnode
16 char *secname;
17 int off_setname;
18 long pri;
19 struct setnode *next;
20 } setnode;
22 static char* pointer_size = "LONG";
23 static char pointer_bytes = 4;
25 static setnode *new_setnode(const char *name, setnode *next, int off, long pri){
26 setnode *n;
28 if (!(n = calloc(1, sizeof(setnode))) ||
29 !(n->secname = strdup(name))
32 fatal("new_setnode()", strerror(errno));
35 n->off_setname = off;
36 n->pri = pri;
37 n->next = next;
39 return n;
42 static setnode *get_setnode(setnode **list, const char *name, int off, long pri)
44 setnode **curr = list;
46 while (*curr)
48 if (strcmp((*curr)->secname, name) == 0)
52 if ((*curr)->pri == pri)
53 return *curr;
55 if ((*curr)->pri > pri)
56 break;
58 curr = &(*curr)->next;
60 } while (*curr && strcmp((*curr)->secname, name) == 0);
62 break;
65 curr = &(*curr)->next;
68 return (*curr = new_setnode(name, *curr, off, pri));
71 void emit_sets(setnode *setlist, FILE *out)
73 char setname_big[201];
74 int i;
76 while (setlist)
78 setnode *oldnode = setlist;
79 i = 0;
83 setname_big[i] = toupper(setlist->secname[setlist->off_setname + i]);
84 } while (setlist->secname[setlist->off_setname + i++]);
86 fprintf
88 out,
89 " __%s_LIST__ = .;\n"
90 " %s((__%s_END__ - __%s_LIST__) / %d - 2)\n",
91 setname_big, pointer_size, setname_big, setname_big, pointer_bytes
96 fprintf
98 out,
99 " KEEP(*(%s.%ld))\n",
100 setlist->secname, setlist->pri
103 setlist = setlist->next;
104 } while (setlist && (strcmp(oldnode->secname, setlist->secname) == 0));
107 fprintf
109 out,
110 " KEEP(*(%s))\n"
111 " %s(0)\n"
112 " __%s_END__ = .;\n",
113 oldnode->secname, pointer_size, setname_big
119 Notes on sections:
120 .ctors/.dtors - up to GCC 4.6 this was the default section where static
121 C++ constructors were placed for majority of targets.
122 .init_array/.fini_array - ARM EABI uses these sections to place static
123 C++ constructors.
124 As of GCC 4.6 the constructors can be placed in .init_array/.fini_array
125 for any target
128 void parse_secname(const char *secname, setnode **setlist_ptr)
130 char *idx;
131 int off;
132 long pri = 0;
134 if (strncmp(secname, ".aros.set.", 10) == 0)
135 off = 10;
136 else
137 if (strncmp(secname, ".ctors", 5) == 0)
138 off = 1;
139 else
140 if (strncmp(secname, ".dtors", 5) == 0)
141 off = 1;
142 else
143 if (strncmp(secname, ".init_array", 11) == 0)
144 off = 1;
145 else
146 if (strncmp(secname, ".fini_array", 11) == 0)
147 off = 1;
148 else
149 return;
151 idx = strchr(secname + off, '.');
152 if (idx)
154 *idx = '\0';
155 pri = strtol(&idx[1], NULL, 10);
158 get_setnode(setlist_ptr, secname, off, pri);
161 void parse_format(const char *format)
163 if (strncmp(format, "elf64", 5) == 0) {
164 pointer_size = "QUAD";
165 pointer_bytes = 8;
169 void emit_libs(setnode *liblist, FILE *out)
171 while (liblist) {
172 fprintf(out, "PROVIDE(%s = .); LONG(%ld)\n", liblist->secname, liblist->pri);
173 liblist = liblist->next;