Skip to content

Commit 3d7f438

Browse files
committed
Adds new dwarf.h checking code in
buildDW_LNAME Adds a build of this new stuff. modified: Makefile.am modified: configure.ac new file: src/bin/buildDW_LNAME/Makefile.am new file: src/bin/buildDW_LNAME/README new file: src/bin/buildDW_LNAME/buildlname.c new file: src/bin/buildDW_LNAME/dwarf_lname_data.h new file: src/bin/buildDW_LNAME/meson.build Corrects a small mistake here (made yesterday) modified: src/bin/checkDW_LANG/Makefile.am Checking code above found an error in dwarf.h DW_LNAME instance 0x21. These three fix it. modified: src/lib/libdwarf/dwarf.h modified: src/lib/libdwarf/dwarf_names.c modified: src/lib/libdwarf/dwarf_query.c
1 parent ec77d00 commit 3d7f438

File tree

11 files changed

+392
-5
lines changed

11 files changed

+392
-5
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SUBDIRS += src/bin/attr_form
2525
SUBDIRS += src/bin/buildopstab
2626
SUBDIRS += src/bin/builduritable
2727
SUBDIRS += src/bin/checkDW_LANG
28+
SUBDIRS += src/bin/buildDW_LNAME
2829

2930
### rebuild is for maintainers to update C source
3031
### that depends on certain (C and/or text) Files.
@@ -40,6 +41,7 @@ rebuild:
4041
make -C src/bin/attr_form rebuild
4142
make -C src/bin/buildopstab rebuild
4243
make -C src/bin/checkDW_LANG rebuild
44+
make -C src/bin/buildDW_LNAME rebuild
4345
doc:
4446
make -C doc doc
4547

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ src/bin/tag_tree/Makefile
510510
src/bin/attr_form/Makefile
511511
src/bin/buildopstab/Makefile
512512
src/bin/checkDW_LANG/Makefile
513+
src/bin/buildDW_LNAME/Makefile
513514
src/bin/builduritable/Makefile
514515
test/Makefile
515516
fuzz/Makefile

src/bin/buildDW_LNAME/Makefile.am

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
###Copyright (C) 2025 David Anderson <davea42 at linuxmail dot org>
2+
###This code is public domain and can be freely used or copied.
3+
4+
AUTOMAKE_OPTIONS=subdir-objects
5+
MAINTAINERCLEANFILES = Makefile.in
6+
CLEANFILES =
7+
rebuild: buildlname
8+
./buildlname -f $(top_srcdir)
9+
noinst_PROGRAMS = buildlname
10+
buildlname_SOURCES = buildlname.c
11+
buildlname_CPPFLAGS = \
12+
-I. -I$(top_srcdir)/src/lib/libdwarf
13+
buildlname_CFLAGS = $(DWARF_CFLAGS_WARN)
14+
15+
EXTRA_DIST = meson.build

src/bin/buildDW_LNAME/README

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
Created 25 October 2025
3+
The intent of this is to build a new
4+
sourcefile dwarf_lname_version.c
5+
with function
6+
int dwarf_language_version_data(
7+
Dwarf_Unsigned dw_lang_name,
8+
int *dw_default_lower_bound,
9+
const char **dw_version_scheme)
10+
in the libdwarf source.
11+
12+
based on the content in dwarf_lname_data.h
13+
and we also verify that dwarf.h has the same
14+
base of LNAMEs as dwarf_lname_data.h
15+
16+
17+
After updating the libdwarf build for this
18+
we will remove that function from libdwarf/dwarf_query.c
19+

src/bin/buildDW_LNAME/buildlname.c

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/*
2+
Copyright (c) 2020, David Anderson
3+
All rights reserved.
4+
5+
This software file is hereby placed in the public domain.
6+
For use by anyone for any purpose.
7+
*/
8+
9+
#include <stdio.h> /* FILE fclose() fopen() fprintf() printf() */
10+
#include <stdlib.h> /* exit() getenv() */
11+
#include <string.h> /* strcmp() strcpy() strncmp() strlen() */
12+
13+
#include "dwarf.h"
14+
#include "dwarf_lname_data.h"
15+
16+
#define MAXDEFINELINE 1000
17+
static char *input_name = 0;
18+
static char pathbuf[BUFSIZ];
19+
static char buffer[BUFSIZ];
20+
21+
#define FALSE 0
22+
#define TRUE 1
23+
24+
static unsigned tcount = sizeof(lnsix) / sizeof(lnsix[0]);
25+
static unsigned int touchcounts[sizeof(lnsix) / sizeof(lnsix[0])];
26+
27+
static void
28+
safe_strcpy(char *targ,char *src,unsigned targlen, unsigned srclen)
29+
{
30+
if (srclen > targlen) {
31+
printf("Target name does not fit in buffer.\n"
32+
"In buildopstabcount.c increase buffer size "
33+
" from %u \n",(unsigned int)sizeof(buffer));
34+
exit(EXIT_FAILURE);
35+
}
36+
strcpy(targ,src);
37+
}
38+
39+
static void
40+
validatetouchcount(char *curdefname,unsigned long v)
41+
{
42+
if (v >= tcount) {
43+
printf("ERROR: For LNAME id 0x%04lx there is "
44+
"No count available, limit is %x. Something wrong!\n",
45+
v,tcount);
46+
exit(EXIT_FAILURE);
47+
}
48+
if (touchcounts[v]) {
49+
printf("ERROR: For LNAME id 0x%04lx we are double "
50+
"counting at count 0x%x . Something wrong!\n",
51+
v,touchcounts[v]);
52+
exit(EXIT_FAILURE);
53+
}
54+
++touchcounts[v];
55+
if (lnsix[v].ln_value != v) {
56+
printf("ERROR: For LNAME id 0x%04lx not at the "
57+
"correct entry vs "
58+
" ln_value 0x%04x\n",
59+
v,lnsix[v].ln_value);
60+
exit(EXIT_FAILURE);
61+
}
62+
if (strcmp(curdefname,lnsix[v].ln_name)) {
63+
printf("ERROR: For LNAME id 0x%04lx we find the"
64+
" wrong string! name %s lnsixname %s \n",
65+
v, curdefname,lnsix[v].ln_name);
66+
exit(EXIT_FAILURE);
67+
}
68+
}
69+
static void
70+
validatefinaltouchcount()
71+
{
72+
unsigned long i = 1;
73+
/* Skip [0], it is not real, just a placeholder.
74+
0 is not a valid LNAME id */
75+
for( ; i < tcount; ++i) {
76+
if (touchcounts[i] != 1) {
77+
printf(" ERROR: an entry in the LNAMES list "
78+
" with DW_LNAME id 0x%04lx has touchcount"
79+
" %u which indicates an error comparing "
80+
" dwarf.h and the lnsix table here.\n",
81+
i,touchcounts[i]);
82+
exit(EXIT_FAILURE);
83+
}
84+
}
85+
}
86+
87+
88+
/* Writes a complete new function
89+
int dwarf_language_version_data(..)
90+
in
91+
dwarf_lname_version.c
92+
93+
Replacing what was in dwarf_query.c for
94+
that function.
95+
96+
We avoid anything in the new source file
97+
representing date or time as we want
98+
re-running this (if no changes in dwarf_lname_data.h)
99+
outputs bit-for-bit identical dwarf_lname_version.c .
100+
*/
101+
102+
103+
static void
104+
write_new_query_function(char *path)
105+
{
106+
107+
printf("Query function not complete. %s\n",path);
108+
}
109+
/* Issue error message and exit there is a mismatch,
110+
this should never fail.
111+
It verifies that dwarf.h DW_LNAME values match
112+
exactly the LNAME values in dwarf_lname_data.h*/
113+
static void
114+
check_if_lname_complete(char *path)
115+
{
116+
FILE *fin = 0;
117+
unsigned int linenum = 1;
118+
int loop_done = FALSE;
119+
const char *oldop = "#define DW_LNAME_";
120+
int oldoplen = strlen(oldop);
121+
int langentry = -1;
122+
unsigned long lastvalue = 0;
123+
124+
fin = fopen(path,"r");
125+
if (!fin) {
126+
printf("Unable to open dwarf.h to read %s\n",path);
127+
exit(EXIT_FAILURE);
128+
}
129+
for ( ;!loop_done;++linenum) {
130+
char *line = 0;
131+
char * pastname = 0;
132+
unsigned int linelen = 0;
133+
char *curdefname = 0;
134+
unsigned int curdefnamelen = 0;
135+
char *endptr = 0;
136+
char *numstart = 0;
137+
unsigned long v = 0;
138+
139+
line = fgets(buffer,MAXDEFINELINE,fin);
140+
if (!line) {
141+
break;
142+
}
143+
linelen = strlen(line);
144+
line[linelen-1] = 0;
145+
--linelen;
146+
if (linelen >= (unsigned)(MAXDEFINELINE-1)) {
147+
printf("define line %u is too long!\n",linenum);
148+
exit(EXIT_FAILURE);
149+
}
150+
if (strncmp(line,oldop,oldoplen)) {
151+
/* Not ours. */
152+
continue;
153+
}
154+
++langentry;
155+
/* ASSERT: line ends with NUL byte. */
156+
curdefname = line+8; /* now past #define */
157+
for ( ; ; curdefnamelen++) {
158+
pastname = curdefname +curdefnamelen;
159+
if (!*pastname) {
160+
/* At end of line. Missing value. */
161+
printf("define line %u of %s: has no number value!\n",
162+
linenum,path);
163+
exit(EXIT_FAILURE);
164+
}
165+
if (*pastname == ' ') {
166+
/* Ok. Now look for value. */
167+
numstart = pastname + 1;
168+
break;
169+
}
170+
}
171+
*pastname = 0; /* so curdefname points to only the name */
172+
/* Skip spaces. */
173+
for ( ; *numstart == ' '; ++numstart) { }
174+
endptr = 0;
175+
v = strtoul(numstart,&endptr,0);
176+
if (v == 0 && endptr == numstart) {
177+
printf("define line %u of %s: number value missing.\n",
178+
linenum,path);
179+
printf("Leaving a space as in #define A B 3"
180+
" in dwarf.h.in will cause this.\n");
181+
exit(EXIT_FAILURE);
182+
}
183+
if (*endptr != ' ' && *endptr != 0) {
184+
unsigned char e = *endptr;
185+
printf("define line %u: number value terminates oddly "
186+
"char: %u 0x%x line %s\n",
187+
linenum,e,e,line);
188+
exit(EXIT_FAILURE);
189+
}
190+
if (!v) {
191+
printf("define line %u: DW_LANG number value "
192+
"zero unreasonable.\n",
193+
linenum);
194+
exit(EXIT_FAILURE);
195+
}
196+
/* v is the DW_LNAM value, 0x0001 for DW_LNAME_Ada */
197+
if (!lastvalue) {
198+
/* Nothing to check yet. Is first DW_LNAME. */
199+
lastvalue = v;
200+
validatetouchcount(curdefname,v);
201+
continue;
202+
}
203+
if (lastvalue == v) {
204+
printf("define line %u: DW_LNAME number value "
205+
" 0x%lx duplicated.\n",
206+
linenum,lastvalue);
207+
exit(EXIT_FAILURE);
208+
}
209+
if (v != (lastvalue +1)) {
210+
printf("define line %u: DW_LNAME number "
211+
" last value 0x%lx after "
212+
" expected 0x%lx, not 0x%lx",
213+
linenum,lastvalue,lastvalue+1,v);
214+
exit(EXIT_FAILURE);
215+
}
216+
validatetouchcount(curdefname,v);
217+
lastvalue = v;
218+
}
219+
validatefinaltouchcount();
220+
fclose(fin);
221+
}
222+
223+
int main(int argc, char**argv)
224+
{
225+
const char *tailpath = "/src/lib/libdwarf/dwarf.h";
226+
char *path = 0;
227+
unsigned len = 0;
228+
229+
if (argc > 1) {
230+
if (argc != 3) {
231+
printf("Expected -f <filename> of base code path\n");
232+
exit(EXIT_FAILURE);
233+
}
234+
if (strcmp(argv[1],"-f")) {
235+
printf("Expected -f\n");
236+
exit(EXIT_FAILURE);
237+
}
238+
path=argv[2];
239+
} else {
240+
/* env var should be set with base path of code */
241+
path = getenv("DWTOPSRCDIR");
242+
if (!path) {
243+
printf("Expected environment variable "
244+
"DWTOPSRCDIR with path of "
245+
"base directory (usually called 'code')\n");
246+
exit(EXIT_FAILURE);
247+
}
248+
}
249+
len = strlen(path);
250+
if (len >= sizeof(pathbuf)) {
251+
printf(" buildopstab Input path greater length "
252+
"than makes any sense:"
253+
" Giving up\n");
254+
exit(EXIT_FAILURE);
255+
256+
}
257+
safe_strcpy(pathbuf,path,sizeof(pathbuf),len);
258+
{
259+
size_t remaining = sizeof(pathbuf) -len -1;
260+
size_t tailpathlen = strlen(tailpath);
261+
if (tailpathlen >= remaining) {
262+
printf(" buildopstab Input tailpath greater "
263+
"length fits in buf: "
264+
"Giving up\n");
265+
exit(EXIT_FAILURE);
266+
}
267+
/* Notice tailpath has a leading / */
268+
safe_strcpy(pathbuf+len,(char *)tailpath,
269+
remaining,tailpathlen);
270+
}
271+
input_name = pathbuf;
272+
273+
check_if_lname_complete(pathbuf);
274+
write_new_query_function(pathbuf);
275+
276+
return 0;
277+
}

0 commit comments

Comments
 (0)