Cannot set Attribute Permissions to 0666 in sysfs - permissions

I am working with sysfs and I need to create a file under sysfs, the file should be readable and writable by all users, for which I set the Permissions in '__ATTR' to 0666. But the module does not compile, the moment I change the permissions to 0660, it compiles correctly.
The Error message that I get with 0666 permissions is as follows
`/home/rishabh/kernel_modules/Task09/task9.c: At top level:
include/linux/bug.h:33:45: error: negative width in bit-field ‘<anonymous>’
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
^
include/linux/kernel.h:859:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
BUILD_BUG_ON_ZERO((perms) & 2) + \
^
include/linux/sysfs.h:102:12: note: in expansion of macro ‘VERIFY_OCTAL_PERMISSIONS’
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
^
/home/rishabh/kernel_modules/Task09/task9.c:65:2: note: in expansion of macro ‘__ATTR’
__ATTR(id, 0666, id_show, id_store);
^
include/linux/bug.h:33:45: warning: initialization from incompatible pointer type [enabled by default]
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
^
include/linux/kernel.h:859:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
BUILD_BUG_ON_ZERO((perms) & 2) + \
^
include/linux/sysfs.h:102:12: note: in expansion of macro ‘VERIFY_OCTAL_PERMISSIONS’
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
^
/home/rishabh/kernel_modules/Task09/task9.c:65:2: note: in expansion of macro ‘__ATTR’
__ATTR(id, 0666, id_show, id_store);
^
include/linux/bug.h:33:45: warning: (near initialization for ‘id_attribute.show’) [enabled by default]
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
^
include/linux/kernel.h:859:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
BUILD_BUG_ON_ZERO((perms) & 2) + \
^
include/linux/sysfs.h:102:12: note: in expansion of macro ‘VERIFY_OCTAL_PERMISSIONS’
.mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \
^
/home/rishabh/kernel_modules/Task09/task9.c:65:2: note: in expansion of macro ‘__ATTR’
__ATTR(id, 0666, id_show, id_store);
^
`
I also tried using __ATTR_RW(_name) macro, but it gives read-write permissions only to root and all others are left with read permission.

If you follow the error messages, the 2nd one is
kernel.h:859:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
BUILD_BUG_ON_ZERO((perms) & 2)
and if you look in kernel.h you will see the comment
#define VERIFY_OCTAL_PERMISSIONS(perms)
...
/* OTHER_WRITABLE? Generally considered a bad idea. */ \
BUILD_BUG_ON_ZERO((perms) & 2) + \
...
So you can see that you are being told that it is a bad idea to make a sysfs file writeable to all. If you really want to do this, you must bypass this macro check. For example, add just before your call of __ATTR() a redefinition of the macro:
/* warning! need write-all permission so overriding check */
#undef VERIFY_OCTAL_PERMISSIONS
#define VERIFY_OCTAL_PERMISSIONS(perms) (perms)

__ATTR_RW(id) should be a correct way (and eudyptula accepted that ;)). Definition in sysfs.h says, that it set rights to 0644, which are correct rights you want - no one, except root user, can't write to /sys/kernel files (and it's specified in the task too).
sysfs.h part:
#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
_name##_show, _name##_store)

Related

How to put a list of cells into a submodule in yosys

I am trying to write a procedure to put each Strongly Connected Component of the given circuit into a distinct sub-module.
So, I tried to add a function to SCC pass in Yosys to add each SCC into a submod. The function is:
void putSelectionIntoParition (RTLIL::Design *design,
std::vector<pair<std::string,RTLIL::Selection>>& SelectionVector)
{
int p_count = 0;
for (std::vector<pair<std::string,RTLIL::Selection>>::iterator it = SelectionVector.begin();
it != SelectionVector.end(); ++it)
{
design->selection_stack[0] = it->second;
design->selection_stack[0].optimize(design);
std::string command = "submod -name ";
command.append(it->first);
Pass::call_on_selection(design, it->second, command);
++p_count;
}
}
However, my code does not work properly.
I guess the problem is with "selection" process that I use. I was wondering if there is any utility/API inside the yosys source that accept vector of cells (as well and a name submodule) and put them into a sub-module.
The following should work just fine:
void putSelectionIntoParition(RTLIL::Design *design,
std::vector<pair<std::string, RTLIL::Selection>> &SelectionVector)
{
for (auto it : SelectionVector) {
std::string command = "submod -name " + it.first;
Pass::call_on_selection(design, it.second, command);
}
}
You definitely don't need (nor should) modify selection_stack.
I was wondering if there is any utility/API inside the yosys source that accept vector of cells (as well and a name submodule) and put them into a sub-module.
You would do this by setting the submod="<name>" attribute on the cells. Then simply run the submod command.
You might have seen that the scc documentation mentions a -set_attr option that is yet unimplemented. I have now implemented this option in commit ef603c6 (commit 914aa8a contains a bugfix for scc).
With this feature you can now accomplished what you have described using something like the following yosys script.
read_verilog test.v
prep
scc -set_attr submod scc{}
submod
show test
I have tested this with the folling test.v file:
module test(input A, B, output X, Y);
assign X = (A & B) ^ X, Y = A | (B ^ Y);
endmodule
3. Executing SCC pass (detecting logic loops).
Found an SCC: $xor$test.v:2$2
Found an SCC: $or$test.v:2$4 $xor$test.v:2$3
Found 2 SCCs in module test.
Found 2 SCCs.

Can macros accept types?

Unless my understanding is incorrect, the following macro
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
*v = (type) fn(L, i)
#define CHECK(chr, type, fn) case chr: \
SET(type, fn); \
break
switch (ctype[0]) {
CHECK('c', char, lua_tonumber);
}
should expand to
int i; // for loop
const char* ctype; // proprietary type string
void** pool = malloc(sizeof(void*) * (nexpected - 1));
size_t poolc = 0;
switch (ctype[0]) {
case 'c':
char* v = (pool[poolc++] = malloc(sizeof(char)));
*v = (char) lua_tonumber(L, i);
break;
}
but upon compilation, I get:
src/lua/snip.m:185:16: error: expected expression
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:9: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:178:23: note: expanded from macro 'SET'
#define SET(type, fn) type* v = (pool[poolc++] = malloc(sizeof(type))); \
^
src/lua/snip.m:185:5: error: use of undeclared identifier 'v'
CHECK('c', char, lua_tonumber);
^
src/lua/snip.m:181:5: note: expanded from macro 'CHECK'
SET(type, fn); \
^
src/lua/snip.m:179:6: note: expanded from macro 'SET'
*v = (type) fn(L, i)
^
2 errors generated.
What is going on here? Isn't the preprocessor a literal text replacement engine? Why is it trying to evaluate expressions?
Keep in mind while this looks like straight C, this is actually clang Objective C (note the .m) under the C11 standard. Not sure if that makes any difference.
I'm a loss at how to continue without expanding the code for each entry.
Your understanding is correct! But you're running into a quirk of the C language. A label, including a case label, must be followed by an expression, not a variable declaration.
You can work around this by inserting a null statement (e.g, 0;) after the case, or by enclosing the case body in a set of braces. A practical way of doing this might be by redefining CHECK as:
#define CHECK(chr, type, fn) \
case chr: { SET(type,fn); } break;

How to fetch the row and column number of error

How to fetch the row and column number of error (i.e which part of string does not follow the grammar rules)?
I am using yacc parser to check the grammar.
Thank you.
you'd better read the dragon book and the aho book that explain and show example of how to write a lex/yacc based compiler.
In order to get line/column of the error, you shall make your lexer preserve the column and line. So in your lexer, you have to declare two globals, SourceLine and SourceCol (of course you can use better non-camel cased names).
In each token production, you have to calculate the column of the produced token, for that purpose I use a macro as follows:
#define Return(a, b, c) \
{\
SourceCol = (SourceCol + yyleng) * c; \
DPRINT ("## Source line: %d, returned token: "a".\n", SourceLine); \
return b; \
}
and the token production, with that macro, is:
"for" { Return("FOR", FOR, 1);
then to keep lines, for each token that makes a new line, I'm using:
{NEWLINES} {
BEGIN(INITIAL);
SourceLine += yyleng;
Return("LINE", LINE, 0);
}
Then in your parser, you can get SourceCol and SourceLine if you declare those as extern globals:
extern unsigned int SourceCol;
extern unsigned int SourceLine;
and now in your parse_error grammar production, you can do:
parse_error : LEXERROR
{
printf("OMG! Your code sucks at line %u and col %u!", SourceLine, SourceCol);
}
of course you may want to add yytext, handle a more verbose error message etc.. But all that's up to you!

How to test if defined macro is empty at compile time (Cbjective-C / c)?

Is it possible to do check if I've got an empty define? IS_EMPTY_OR_UNDEFINED is a fictive macro I just came up with.
#define constantA 0
#define constantB 1
#define constantC null
#define constantF ""
#define constantH
#if IS_EMPTY_OR_UNDEFINED(constantA)
# error constantA is defined 0 and the above if should not be true - this line should not run
#endif
#if IS_EMPTY_OR_UNDEFINED(constantB)
# error constantB is defined 1 and the above if should not be true - this line should not run
#endif
#if IS_EMPTY_OR_UNDEFINED(constantC)
# error constantC is defined null and the above if should not be true - this line should not run
#endif
#if IS_EMPTY_OR_UNDEFINED(constantF)
# error constantF is defined "" and the above if should not be true - this line should not run
#endif
#if ! IS_EMPTY_OR_UNDEFINED(constantH)
# error constantH is defined empty and the above if should not be true - this line should not run
#endif
#if defined(undefinedConstant) && ! IS_EMPTY_OR_UNDEFINED(undefinedConstant)
# error undefinedConstant is not defined and the above if should not be true - this line should not run
#endif
Checking if an expression is empty can be done (modulo some really exotic border case) but the technique is somewhat complicated. P99 has a macro that does this and which you could be using as
#if !defined(constantA) || P99_IS_EMPTY(constantA)
...
#endif
Combining this in one single macro is not allowed by the C standard. AS of C11 6.10.1 p4, the token defined is not allowed inside macros or other expressions.
You can use #ifdef MACRO or #if defined(MACRO) to test if macros are defined at all. You can also compare them, although only against integers:
#if MACRO > 5
etc. Maybe this helps you?
Edit: Although I don't know how you would check if a definition evaluates to "empty", or if this is possible.

Undeclared Identifier 'L' in Objective-C

I'm developing an app for Mac OS, which includes a cross-platform lib in C++. There's a macro defined as follows:
#define MY_GET(DataType,DataName,PtrFunName,DefaultVaule) \
DataType Get##DataName() \
{ \
DataType dataTem = (DefaultVaule);\
if (NULL == p) \
{ \
return dataTem; \
} \
p->Get##PtrFunName(CComBSTR(L#DataName),&dataTem); \
return dataTem; \
}
When compiling, the compiler generates the following error:
Use of undeclared identifier 'L'
Which is expanded from macro 'MY_GET'. After searching for CComBSTR(L, I can find other usage of L"String". So why is the L expanded from my macro is undefined while other L are compiled successfully.
Is L"String" legal in Objective-C?
I seems that you need the preprocessor "token concatenation" operator ## here:
CComBSTR(L ## #DataName)
instead of
CComBSTR(L#DataName)
The following code in an Objective-C file compiles and produces the wchar_t string L"abc":
#define LL(x) L ## #x
wchar_t *s = LL(abc); // expands to: L"abc"
I don't know if other compilers behave differently, but the Apple LLVM 4.1 compiler does not a allow a space between L and the string:
#define LL(x) L#x
wchar_t *s = LL(abc); // expands to: L "abc"
// error: use of undeclared identifier 'L'