ctfconv/DWARF & clang static variables

2019-11-06 Thread Martin Pieuchot
When a static variable is defined in a function, clang(1) emits the
following DWARF:

 <1><90>: Abbrev Number: 9 (DW_TAG_subprogram)
  DW_AT_name: (indirect string, offset: 0x213b): pageflttrap
  [...]
 <2>: Abbrev Number: 10 (DW_TAG_variable)
  DW_AT_name: (indirect string, offset: 0xc9): faultbuf
  [...]
 <2>: Abbrev Number: 11 (DW_TAG_formal_parameter)
 DW_AT_name: (indirect string, offset: 0x217d): frame
  [...]
 <2>: Abbrev Number: 11 (DW_TAG_formal_parameter)
 DW_AT_name: (indirect string, offset: 0x2183): usermode
  [...]

As you can see the function arguments are placed *after* the local static
variable.  ctfconv(1) currently stops parsing a `DW_TAG_subprogram' section
as soon as it find a variable definition.  That means with modern clang(1)
functions like panic(9) or pageflttrap() are incorrectly identified as having
no argument.

Diff below fixes that, ok?

Index: parse.c
===
RCS file: /cvs/src/usr.bin/ctfconv/parse.c,v
retrieving revision 1.11
diff -u -p -r1.11 parse.c
--- parse.c 31 Jan 2018 14:47:13 -  1.11
+++ parse.c 6 Nov 2019 13:43:32 -
@@ -1138,12 +1142,19 @@ subparse_arguments(struct dwdie *die, si
 * Nested declaration.
 *
 * This matches the case where a ``struct'', ``union'',
-* ``enum'' or ``typedef'' is first declared "inside" a
-* function declaration.
+* ``enum'', ``typedef'' or ``static'' variable is first
+* declared inside a function declaration.
 */
-   if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type ||
-   tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef)
+   switch (tag) {
+   case DW_TAG_structure_type:
+   case DW_TAG_union_type:
+   case DW_TAG_enumeration_type:
+   case DW_TAG_typedef:
+   case DW_TAG_variable:
continue;
+   default:
+   break;
+   }
 
if (tag != DW_TAG_formal_parameter)
break;



Re: Stop using static variables in ICMP

2013-08-19 Thread Mike Belopuhov
On 9 August 2013 11:04, Martin Pieuchot mpieuc...@nolizard.org wrote:
 This is the last episode from the first season of the serie, move
 your variables to the stack.  Like in the previous episodes, this
 one will let us execute the various icmp functions in parallel
 without risk of trashing a value.

 It also reduces the difference with the icmp6 code adding a redirect
 route.

 ok?


OK



Stop using static variables in ICMP

2013-08-09 Thread Martin Pieuchot
This is the last episode from the first season of the serie, move
your variables to the stack.  Like in the previous episodes, this
one will let us execute the various icmp functions in parallel
without risk of trashing a value.

It also reduces the difference with the icmp6 code adding a redirect
route.

ok?

Index: netinet/ip_icmp.c
===
RCS file: /home/ncvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.104
diff -u -p -r1.104 ip_icmp.c
--- netinet/ip_icmp.c   8 Aug 2013 14:59:22 -   1.104
+++ netinet/ip_icmp.c   9 Aug 2013 08:40:27 -
@@ -297,10 +297,6 @@ icmp_error(struct mbuf *n, int type, int
icmp_send(m, NULL);
 }
 
-struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
-static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
-static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
-
 /*
  * Process a received ICMP message.
  */
@@ -309,14 +305,11 @@ icmp_input(struct mbuf *m, ...)
 {
struct icmp *icp;
struct ip *ip = mtod(m, struct ip *);
-   int icmplen;
-   int i;
+   struct sockaddr_in sin;
+   int icmplen, i, code, hlen;
struct in_ifaddr *ia;
void *(*ctlfunc)(int, struct sockaddr *, u_int, void *);
-   int code;
-   int hlen;
va_list ap;
-   struct rtentry *rt;
struct mbuf *opts;
 
va_start(ap, m);
@@ -479,10 +472,13 @@ icmp_input(struct mbuf *m, ...)
if (icmpprintfs)
printf(deliver to protocol %d\n, icp-icmp_ip.ip_p);
 #endif
-   icmpsrc.sin_addr = icp-icmp_ip.ip_dst;
+   bzero(sin, sizeof(sin));
+   sin.sin_family = AF_INET;
+   sin.sin_len = sizeof(struct sockaddr_in);
+   sin.sin_addr = icp-icmp_ip.ip_dst;
 #if NCARP  0
if (m-m_pkthdr.rcvif-if_type == IFT_CARP 
-   carp_lsdrop(m, AF_INET, icmpsrc.sin_addr.s_addr,
+   carp_lsdrop(m, AF_INET, sin.sin_addr.s_addr,
ip-ip_dst.s_addr))
goto freeit;
 #endif
@@ -492,7 +488,7 @@ icmp_input(struct mbuf *m, ...)
 */
ctlfunc = inetsw[ip_protox[icp-icmp_ip.ip_p]].pr_ctlinput;
if (ctlfunc)
-   (*ctlfunc)(code, sintosa(icmpsrc), m-m_pkthdr.rdomain,
+   (*ctlfunc)(code, sintosa(sin), m-m_pkthdr.rdomain,
icp-icmp_ip);
break;
 
@@ -538,14 +534,17 @@ icmp_input(struct mbuf *m, ...)
 * We are not able to respond with all ones broadcast
 * unless we receive it over a point-to-point interface.
 */
+   bzero(sin, sizeof(sin));
+   sin.sin_family = AF_INET;
+   sin.sin_len = sizeof(struct sockaddr_in);
if (ip-ip_dst.s_addr == INADDR_BROADCAST ||
ip-ip_dst.s_addr == INADDR_ANY)
-   icmpdst.sin_addr = ip-ip_src;
+   sin.sin_addr = ip-ip_src;
else
-   icmpdst.sin_addr = ip-ip_dst;
+   sin.sin_addr = ip-ip_dst;
if (m-m_pkthdr.rcvif == NULL)
break;
-   ia = ifatoia(ifaof_ifpforaddr(sintosa(icmpdst),
+   ia = ifatoia(ifaof_ifpforaddr(sintosa(sin),
m-m_pkthdr.rcvif));
if (ia == 0)
break;
@@ -579,6 +578,12 @@ reflect:
return;
 
case ICMP_REDIRECT:
+   {
+   struct sockaddr_in sdst;
+   struct sockaddr_in sgw;
+   struct sockaddr_in ssrc;
+   struct rtentry *newrt = NULL;
+
/* Free packet atttributes */
if (m-m_flags  M_PKTHDR)
m_tag_delete_chain(m);
@@ -598,8 +603,15 @@ reflect:
 * listening on a raw socket (e.g. the routing
 * daemon for use in updating its tables).
 */
-   icmpgw.sin_addr = ip-ip_src;
-   icmpdst.sin_addr = icp-icmp_gwaddr;
+   bzero(sdst, sizeof(sdst));
+   bzero(sgw, sizeof(sgw));
+   bzero(ssrc, sizeof(ssrc));
+   sdst.sin_family = sgw.sin_family = ssrc.sin_family = AF_INET;
+   sdst.sin_len = sgw.sin_len = ssrc.sin_len = sizeof(sdst);
+   bcopy(icp-icmp_ip.ip_dst, sdst.sin_addr, sizeof(sdst));
+   bcopy(icp-icmp_gwaddr, sgw.sin_addr, sizeof(sgw));
+   bcopy(ip-ip_src, ssrc.sin_addr, sizeof(ssrc));
+
 #ifdef ICMPPRINTFS
if (icmpprintfs) {
char buf[4 * sizeof(123)];
@@ -610,27 +622,25 @@ reflect:
buf, inet_ntoa(icp-icmp_gwaddr));
}
 #endif
-   icmpsrc.sin_addr = 

Static variables

2013-07-08 Thread Maxime Villard
Hi,
is it normal that in some functions like

tc_ticktock(void)
{
static int count;

if (++count  tc_tick)
return;
count = 0;
tc_windup();
}

the static variables are not initialized?

- kern_tc.c l.547
- kern_resource.c l.499
- kern_sched.c l.106
- subr_extent.c l.130
- ...



Re: Static variables

2013-07-08 Thread Franco Fichtner
Hi Maxime,

On Jul 8, 2013, at 10:40 AM, Maxime Villard rusty...@gmx.fr wrote:

 the static variables are not initialized?

Static variables are always zeroed when not specified otherwise.


Regards,
Franco



Re: Static variables

2013-07-08 Thread Maxime Villard
Le 08/07/2013 11:00, Franco Fichtner a écrit :
 Hi Maxime,
 
 On Jul 8, 2013, at 10:40 AM, Maxime Villard rusty...@gmx.fr wrote:
 
 the static variables are not initialized?
 
 Static variables are always zeroed when not specified otherwise.
 
 
 Regards,
 Franco
 
 

Ah, yes. I didn't know.



Re: Static variables

2013-07-08 Thread Matthew Dempsky
On Mon, Jul 8, 2013 at 2:06 AM, Maxime Villard rusty...@gmx.fr wrote:
 Ah, yes. I didn't know.

For what it's worth, this is specified in C99 §6.7.8 (Initializaton)
paragraph 10:

If an object that has static storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively)
according to these rules;
— if it is a union, the first named member is initialized (recursively)
according to these rules.

On OpenBSD (and most, if not all, ELF platforms), this is implemented
by assigning these objects into the .bss section, which is initialized
to all zero bytes at program startup, taking advantage of the fact
that all of our platforms represent null pointers and zero values as
sequences of zero bytes.